- JSLearn-ES6 'ES6語法學習'
JavaScript基礎知識剖析
01 變量與原型
-
01-01
變量類型和計算(1)
-
01-02
變量類型和計算(2)
-
01-03
變量類型和計算(3)-JSON的理解
-
01-04
原型與原型鏈-構造函數
-
01-05
原型規則和示例
-
01-06
原型鏈
-
01-07
instanceof
-
01-08
知識點小結 & 解決問題
02
03
04
05
06
07
-
07-01
上線回滾-上線回滾流程
08 JS算法
09 函數應用
-
09-01
JavaScript算法測試函數
JS小練習
- JSDemo JS小程序
- JDMenu 京東無延遲菜單
- DatePicker組件開發
- 手風琴效果開發
知識點學習
01-01
變量類型和計算(1)
- JS中使用typeof能得到的哪些類型
- 何時使用
===
何時使用==
- JS中有哪些內置函數
- JS變量按照
存儲方式
區分為哪些類型,并描述其特點 - 如何理解
JSON
值類型
- 從內存來說值類型是把每一個值存儲在變量類型的每一個位置
var a = 100;
var b = a;
a = 200
console.log(b);//100
引用類型
- 把a賦值*-成一個對象,a的位置是通過指針指向一個位置
- 把b賦值成a,其實是定義一個b,b的指針指向了那個對象位置
- 也就是有兩份
age:20
的對象 - 對象的引用,就相當于復寫一個對象,這兩個對象之間相互獨立
- 引用類型:對象、數組、函數
var a ={age:20};
var b = a;
b.age = 21;
console.log(a.age); //21
- typeof運算符
typeof undefined //undefined
typeof 'abc' // String
typeof 123 //number
typeof true //boolean
typeof {} //object
typeof [] //object
typeof null //object
typeof console.log //funciton
變量計算-強制類型轉換
- 字符串拼接
var a = 100 + 10;//110
var b = 100 + '10';//10010
- == 運算符
100 == '100' //true
0 == '' //true
null == undefined //true
- if語句
var a = true;
if(a){
//....
}
var b = 100;
if (b) {
//....
}
var c = '';
if (c) {
//...
}
- 邏輯運算
console.log(10 && 0); //0
console.log('' || 'abc'); //abc
console.log(!window.acb); //true
//判斷一個變量會被當做true還是false
var a = 100;
console.log(!!a);//true
01-02
變量類型和計算(2)
JS中使用typeof能得到的類型
//問題:JS中使用typeof能得到哪些類型
typeof undefined //undefined
typeof 'abc' // String
typeof 123 //number
typeof true //boolean
typeof {} //object
typeof [] //object
typeof null //object
typeof console.log //funciton
- 總結來說typeof可以得到
undefined、String、number、boolean
可以區分值類型,但對于引用類型無法很細的區分,只能區分函數。 - 尤其是
typeof null object
它是一個引用類型
何時使用 === 和 ==
//問題:何時使用===何時使用==
if (obj.a == null) {
//這里相當于 obj.a === null || obj.a === undefined,簡寫形式
//這是jquery源碼中推薦的寫法
}
JS中的內置函數
//問題:JS中有哪些內置函數----數據封裝類對象
//作為構造函數的作用
Object
Array
Boolean
Number
String
Function
Date
RegExp
Error
JS按照存儲方式區分變量類型
//JS 變量按照存儲方式區分為哪些類型,并描述其特點
//值類型
var a = 10;
var b = a;
a = 11;
console.log(b); // 10
//引用類型
var obj1 = {x:100}
var obj2 = obj1;
obj1.x = 200;
console.log(obj2.x); // 200
- ES中,引用類型是一種數據結構,用于將數據和功能組織在一起
01-03
變量類型和計算(3)-理解JSON
//問題:如何理解JSON
//JSON只不過是一個JS對象
//JSON也是一個數據格式
JSON.stringify({a:10,b:20});
JSON.parse('{"a":10."b":20}')
01-04
原型與原型鏈-構造函數
- 如何準確判斷一個變量數組類型
- 寫一個原型鏈繼承的例子
- 描述new一個對象的過程
- zepto(或其他框架)源碼中如何使用原型鏈
知識點
- 構造函數
- 構造函數-擴展
- 原型規則和示例
- 原型鏈
- instanceof
構造函數
- 自己的想法
普通的函數就像是按步驟執行的動作,而構造函數更像是可更改零件的木偶,普通函數可以直接調用,但是構造函數需要new
因為構造函數也是函數,所以可以直接被調用,但是它的返回值為undefine,此時構造函數里面的this對象等于全局this對象
- 擴展
實例和對象的區別,從定義上來講:1、實例是類的具象化產品,2、而對象是一個具有多種屬性的內容結構。
funciton Foo(name,age){
this.name = name;
this.age = age;
this.class = 'class-1';
// return this //默認有這一行
}
var f = new Foo('zhangsan',20); //實例化對象
// var f1 = new Foo('lisi',22) //創建多個對象
構造函數-擴展
-
var a = {}
其實是var a = new Object()
的語法糖 -
var a = []
其實是var a = new Array()
的語法糖 -
function Foo(){...}
其實是var Foo = new Function(...)
- 使用
instanceof
判斷一個函數是否是一個變量的構造函數- 如果想判斷一個變量是否為“數組”:變量
instanceof Array
- 如果想判斷一個變量是否為“數組”:變量
01-05
原型規則和示例
- 5條原型規則
- 原型規則是學習原型鏈的基礎
第1條
- 所有的引用類型(數組、對象、函數),都具有對象特質、即可自由擴展屬性(除了“NULL”以外)
var obj = {}; obj.a = 100;
var arr = []; arr.a = 100;
function fn(){
fn.a=100;
}
第2條
- 所有的引用類型(數組、對象、函數),都有一個
__proto__
(隱式原型)屬性,屬性值是一個普通的對象
console.log(obj.__proto__);
console.log(arr.__proto__);
console.log(fn.__proto__);
第3條
-
prototype
解釋為JavaScript開發函式庫及框架 - 所有的函數,都有一個
prototype
(顯示原型)屬性,屬性值也是一個普通對象。
console.log(fn.prototype);
第4條
- 所有引用類型(數組、對象、函數),
__proto__
屬性值指向它的構造函數的prototype
屬性值
console.log(obj.__proto__ === Object.prototype);
第5條
- 當試圖得到一個對象的某個屬性時,如果這個對象本身沒有這個屬性,那么會去它的
__proto__
(即它的構造函數prototype
)中尋找
//構造函數
function Foo(name,age){
this.name = name;
}
Foo.prototype.alertName = function () {
alert(this.name);
}
//創建示例
var f = new Foo('zhangsan')
f.printName = function () {
console.log(this.name);
}
//測試
f.printName();
f.alertName();
- this
循環對象自身屬性
var item;
for (item in f) {
//高級瀏覽器已經在for in 中屏蔽了來自原型的屬性
//但是這里建議大家還是加上這個判斷,保證程序的健壯性
if(f.hasOwnProperty(item)) {
console.log(item);
}
}
01-06
原型鏈
//構造函數
function Foo(name,age){
this.name = name;
}
Foo.prototype.alertName = function (){
alert(this.name);
}
//創建示例
var f = new Foo('zhangsan');
f.printName = function () {
console.log(this.name);
}
//測試
f.printName();
f.alertName();
f.toString(); // 要去f.__proto__.__proto__中查找
原型鏈視圖

原型鏈圖
01-07
instanceof
- 用于判斷
引用類型
屬于哪個構造函數
的方法 -
f instanceof Foo
的判斷邏輯是: -
f
的__proto__
一層一層往上走,是否能對應到Foo.prototype
- 再試著判斷f instanceof Object
01-08
知識點小結 & 解決問題
如何準確判斷一個變量是數組類型
var arr = [];
arr instanceof Array; //true
typeof arr //object typeof是無法判斷是否是數組
寫一個原型鏈繼承的例子
//動物
function Animal(){
this.eat = function () {
console.log('animal eat');
}
}
//狗??
function Dog(){
this.bark = function () {
console.log('dog bark');
}
}
Dog.prototype = new Animal();
//哈士奇
var hashiqi = new Dog();
//如果要真正寫,就要寫更貼近實戰的原型鏈
- 推薦 阮一峰老師?????的兩篇文章:Javascript 面向對象編程(一):封裝、Javascript繼承機制的設計思想
描述new一個對象的過程
- 創建一個新對象
- this指向這個新對象
- 執行代碼,即對this賦值
- 返回this ??
function Foo(name,age){
this.name = name ;
this.age = age ;
//return this //默認有這一行
}
var f = new Foo('zhangsan',20);
//var f1 = new Foo('list',22) //創建多個對象
zepto(或其他框架)源碼中如何使用原型鏈
- 。。。。。。
貼近實際開發原型鏈繼承的例子
function Elem(id) {
this.elem = document.getElementById(id);
}
Elem.prototype.html = function (val) {
var elem = this.elem;
if (val) {
elem.innerHTML = val;
return this; // 鏈式操作
}else {
return elem.innerHTML;
}
}
Elem.prototype.on = function (type, fn) {
var elem = this.elem ;
elem.addEventListener(type, fn) ;
}
var div1 = new Elem('div1');
//console.log(div1.html());
div1.html('<p>hello imooc</p>')
div1.on('click',function () {
alert('click')
})
02-01
作用域和閉包-執行上下文
- 說一下對變量提升的理解
- 說明
this
幾種不同的使用場景 - 創建10個
<a>
標簽,點擊的時候彈出來對應的序號 - 如何理解作用域
- 實際開發中閉包的應用
知識點梳理
- 執行上下文
- this
- 作用域
- 作用域鏈
- 閉包
執行上下文
console.log(a); // undefined
var a = 100;
fn('zhangsan') // 'zhangsan' 20
function fn(name) {
age = 20;
console.log(name, age);
var age;
}
- 范圍:一段<script>或者一個函數
- 全局:變量定義、函數聲明
- 函數:變量定義、函數聲明、this、arguments
- 注意??“函數聲明”和“函數表達式”的區別
fn()
function fn() {
//聲明
}
fn1()
var fn1 = function () {
//表示
}
var a = 100; //類似于這個
//全局聲明
console.log(a);
var a = 100;
fn('zhangsan')
function fn(name) {
console.log(this);
age = 20;
console.log(name,age);
var age;
bar(100);
function bar(num) {
console.log(num);
}
}
02-01
作用域和閉包-this
- this 要在執行時才能確認值,定義時無法確認值
var a = {
name:'A',
fn:function(){
console.log(this.name);
}
}
a.fn() //this === A
a.fn.call({name:'B'}) //this === {name:'B'}
var fn1 = a.fn;
fn1() //this === window
- 作為構造函數執行
- 作為對象屬性執行
- 作為普通函數執行
- call apply bind
function Foo(name){
this.name = name;
}
var f = new Foo('zhangsan');
var obj = {
name:'A',
printName:function(){
console.log(this.name);
}
}
obj.printName()
function fn(){
console.log(this);
}
fn()
// call apply bind
function fn1(name) {
alert(name);
console.log(this);
}
fn1.call({x:100},'zhangsan',20);
// bind
var fn2 = function fn2(name) {
alert(name);
console.log(this);
}.bind({y:200});
fn2('zhangsan',20);
02-03
作用域和閉包-作用域
作用域
- 沒有塊級作用域
- 只有函數和全局作用域
//無塊級作用域
if(true){
var name = 'zhangsan';
}
console.log(name);
//函數和全局作用域
var a = 100;
function fn() {
var a = 200;
console.log('fn',a);
}
console.log('global',a);
fn();
- 作用域鏈
var a = 100;
function fn() {
var b = 200;
//但錢作用域沒有定義變量,即“自由變量”
console.log(a);
console.log(b);
}
fn();
var a = 100;
function F1() {
var b = 200;
function F2() {
var c = 300;
console.log(a);//a是自由變量。形成一個鏈式結構,向父級去查找
console.log(b);//b是自由變量
console.log(c);//
}
}
02-04
作用域和閉包-閉包
- 函數作為返回值
function F1() {
var a = 100;
//返回一個函數(函數作為返回值)
return function () {
console.log(a);//自由變量,父作用域中查找
}
}
//f1得到一個函數
var f1 = F1();
var a = 200;
f1();
- 函數作為參數傳遞
function F1() {
var a = 100;
return function () {
console.log(a); //自由變量,父作用域中查找
}
}
var f1 = F1();
function F2(fn) {
var a = 200;
fn();
}
F2(f1);
02-05
知識點小結 & 解決問題
對變量提升的理解
- 變量定義
- 函數聲明(注意和函數表達式的區別)
this幾種不停的使用場景
- 作為構造函數執行
- 作為對象屬性執行
- 作為普通函數執行
- call apply bind
function Foo(name){
this.name = name;
}
var f = new Foo('zhangsan');
var obj = {
name:'A',
printName:function(){
console.log(this.name);
}
}
obj.printName()
function fn(){
console.log(this);
}
fn()
// call apply bind
function fn1(name) {
alert(name);
console.log(this);
}
fn1.call({x:100},'zhangsan',20);
// bind
var fn2 = function fn2(name) {
alert(name);
console.log(this);
}.bind({y:200});
fn2('zhangsan',20);
創建10個<a>標簽 點擊的時候彈出來對應的序號
- 錯誤寫法
//這是一個錯誤的寫法!??!
var i,a;
for (var i = 0; i < 10; i++) {
a = document.createElement('a');
a.innerHTML = i + '<br>';
a.addEventListener('click',function (e) {
e.preventDefault();
alert(i)
})
document.body.appendChild(a);
}
//輸出為如下: <a>"9"<br></a>
- 正確寫法
//這是一個正確寫法?。?!
var i;
for (i = 0; i < 10; i++) {
(function(i){
var a = document.createElement('a');
a.innerHTML = i + '<br>';
a.addEventListener('click',function (e) {
e.preventDefault();
alert(i);
})
document.body.appendChild(a);
})(i)
}
如何理解作用域
- 自由變量
- 作用域鏈,即自由變量的查找
- 閉包的兩個場景
實際開發中閉包的應用
//閉包實際應用中主要作用于封裝變量,收取權限
function isFirstLoad() {
var _list = [];
return function (id) {
if(_list.indexOf(id) >= 0){
return false;
}else {
_list.push(id);
return true;
}
}
}
// 應用
var firstLoad = isFirstLoad()
firstLoad(10) // true
firstLoad(10) // false;
firstLoad(20) // true
03-01
異步和單線程-什么是異步
- 同步和異步的區別是什么?分別舉一個同步和異步的例子
- 一個關于setTimeout的筆試題
- 前端使用異步的場景有哪些
異步知識點
- 什么是異步(對比同步)
- 前端使用異步的場景
- 異步與單線程
什么是異步
console.log(100); // step1
setTimeout(function () {
console.log(200); // step3
},1000);
console.log(300); // step2
對比同步
console.log(100);
alert(200) // 1秒鐘后點擊確認
console.log(300);
何時需要異步
- 在可能發生等待的情況
- 等待過程中不能像alert一樣阻塞程序運行
- 因此,所有的
所有的等待情況
都需要異步
前端使用異步的場景
- 定時任務:
setTimeout,setInverval
- 網絡請求:
ajax請求
,動態<img>加載
//ajax請求
console.log('start');
$.get('./data1.json',function (data1) {
console.log(data1);
})
console.log('end');
//<img>加載示例
console.log('start');
var img = document.createElement('img');
img.onload = function () {
console.log('loaded');
}
img.src = '/xxx.png';
console.log('end');
- 事件綁定
03-02
異步和單線程-單線程
console.log(100); // step1
setTimeout(function () {
console.log(200); // step3
});
console.log(300); // step2
- 從上面代碼中理解單線程
- 執行第一行,打印100
- 執行setTimeout后,傳入setTimeout的函數會被暫存起來,不會立即執行(單線程的特點,不能同時干兩件事)
- 執行最后一行打印300
- 待所有程序執行完,處于空閑狀態時,會立馬看有沒有暫存起來的要執行
- 發現暫存起來的
setTimeout
中的函數無需等待時間,就立即來過來執行
解答:異步與單線程
- 同步和異步的區別是什么?分別舉一個同步和異步的例子
- 同步會阻塞代碼執行,而異步不會
-
alert
是同步,setTimeout
是異步
- 一個關于setTimeout的筆試題
- 可以說
setTimeout
是等待頁面加載完畢后,在進行加載
console.log(1);
setTimeout(function () {
console.log(2);
},0)
console.log(3);
setTimeout(function () {
console.log(4);
},1000)
console.log(5);
- 前端使用異步的場景有哪些
- 定時任務:
setTimeout,setInverval
- 網絡任務:
ajax
請求,動態<img>
加載 - 事件綁定
- 定時任務:
03-03
其他知識點-日期和Math
獲取 2017-06-10 格式的日期
Date.now(); // 獲取當前時間毫秒數
var dt = new Date();
dt.getTime() // 獲取毫秒數
dt.getFullYear() // 年
dt.getMonth() // 月(0-11)
dt.getDate() // 日(0-31)
dt.getHours() // 小時(0-23)
dt.getMinutes() // 分鐘(0-59)
dt.getSeconds() // 秒 (0-59)
獲取隨機數,要求時長度一致的字符串格式
-
Math
獲取隨機數Math.random()
03-04
其他知識點-數組和對象的API
寫一個能遍歷對象和數組的通用forEach函數
數組API
-
forEach
便利所有元素
var arr = [1,2,3];
arr.forEach(function (item,index) {
//遍歷數組所有元素
console.log(index,item);
})
-
every
判斷所有元素是否都符合條件
var arr = [1,2,3];
var result = arr.every(function (item,index) {
if (item<4) {
//用于判斷所有的數組元素,都滿足一個條件
return true;
}
})
console.log(result);
-
some
判斷是否有至少一個元素符合條件
var arr = [1,2,3];
var result = arr.some(function (item,index) {
// 用來判斷所有的數組元素,只要有一個滿足條件即可
if (item<2) {
return true;
}
})
console.log(result);
-
sort
排序
var arr = [1,4,2,3,5]
var arr2 = arr.sort(function (a,b) {
//從小到大排序
return a - b;
//從大到小排序
//return b - a
})
console.log(arr2);
-
map
對元素重新組裝,生成新數組
var arr = [1,2,3,4]
var arr2 = arr.map(function functionName(item,index) {
//將元素重新組裝,并返回
return '<b>' + item + '</b>';
})
console.log(arr2);
-
filter
過濾符合條件的元素
var arr = [1,2,3];
var arr2 = arr.filter(function (item,index) {
//通過某一個條件過濾數組
if(item >= 2){
return true;
}
})
console.log(arr2);
對象API
var obj = {
x: 100,
y: 200,
z: 300
}
var key
for (key in obj) {
// 注意這里的hasOwnProperty,請查看原型鏈
if (obj.hasOwnProperty(key)) {
console.log(key,obj[key]);
}
}
- 舉個例子
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Register</title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
</head>
<body>
<script type="text/javascript">
console.log(Date.now());
var dt = new Date();
console.log(dt);
console.log(dt.getTime());
console.log(dt.getFullYear());
console.log(dt.getDate());
var arr = [1,2,3,4]
arr.forEach(function (item,index) {
console.log(index,item);
})
</script>
</body>
</html>
問題解答
- 獲取2017-06-10格式的日期
function formatDate(dt) {
if (!dt) {
dt = new Date();
}
var year = dt.getFullYear();
var month = dt.getMonth() + 1;
var date = dt.getDate();
if (month < 10) {
//強制轉換類型
month = '0' + month;
}
if (date < 10) {
//強制轉換類型
date = '0' + date;
}
//強制轉換類型
return year + '-' + month + '-' + date;
}
var dt = new Date();
var formatDate = formatDate(dt);
console.log(formatDate);
- 獲取隨機數,要求是長度一致的字符串格式
var random = Math.random();
var random = random + '0000000000'; //后面加上10個0
var random = random.slice(0,10);
console.log(random);
- 寫一個能遍歷對象和數組的通用forEach函數
//do
var arr = [1,2,3];
//注意,這里的參數的順序換了,為了和對象的遍歷格式一致
forEach(arr,function (index,item) {
console.log(index.item);
})
var obj = {x:100,y:200};
forEach(obj,function (key,value) {
console.log(key,value);
})
//init
function forEach(obj,fn) {
var key;
if (obj instanceof Array) {
//準確判斷是不是一個數組
obj.forEach(function (index.item) {
fn(index,item);
})
}else {
//不是數組就是對象
for (key in obj){
fn(key,obj[key]);
}
}
}
04-01
從基礎知識到JS-Web-API
- 變量類型和計算
- 原型和原型鏈
- 閉包和作用域
- 異步和單線程
- 其他(如日期、Math、各種常用API)
特點
- 特點:表面上來看不能用于工作中開發代碼
- 內置函數:
Object Array Boolean String ......
- 內置對象:
Math JSON ...
- 我們連在網頁彈出一句
Hello World
都不能實現
JS-Web-API
- JS基礎知識:ECMA 262標準
- JS-Web-API:W3C標準
- W3C標準中關于JS的規定有:
- DOM操作
- BOM操作
- 事件綁定
- ajax請求(包含http協議)
- 存儲
基本操作
- 頁面彈框是
windows.alert(123)
,瀏覽器需要做:- 定義一個
windows
全局變量,對象類型; - 給它定義一個
alert
屬性,屬性值是一個函數;
- 定義一個
- 獲取元素document.getElementById(id),瀏覽器需要:
- 定義一個document全局變量,對象屬性;
- 給它定義一個getElementById的屬性,屬性值是一個函數;
- W3C標準沒有規定任何JS基礎相關的東西;
- 不管什么變量類型、原型、作用域和異步
- 只管定義用于瀏覽器中JS操作頁面的API和全局變量
- 全面考慮,JS內置的全局函數和對象有哪些?
- 之前ECMA的
- 比如 window document
- 所有未定義的全局變量,如
navigator.userAgent
總結
- 常說的JS(瀏覽器執行的JS)包含兩個部分:
- JS基礎知識(ECMA262標準);
- JS-Web-API(W3C標準);
04-02
DOM操作
- Document Object Model
- DOM是哪種基本的數據結構
- DOM操作的常用API有哪些
- DOM節點的attr和property有和區別
DOM的本質
- XML
<?xml version="1.0" encoding="UTF-8"?>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Dont forget me this weekend</body>
<other>
<a></a>
<b></b>
</other>
</note>
- XML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Document</title>
</head>
<body>
<div>
<p>this is p</p>
</div>
</body>
</html>
04-03
DOM節點操作
- 獲取DOM節點
- prototype,獲取JS對象上的屬性
- Attribute,獲取DOM標簽上的屬性
獲取DOM節點
var div1 = document.getElementById('div1'); //元素
var divList = document.getElementByTagName('div'); //集合
console.log(divList.length);
console.log(divList[0]);
var containerList = document.getElementByClassName('.container'); //集合
var pList = document.querySelectorAll('p'); //集合
property
var pList = document.querySelectorAll('p');
var p = pList[0];
console.log(p.style.width); // 獲取樣式
p.style.width = '100px' // 修改樣式
console.log(p.className);//獲取class
p.className = 'p1' //修改class
// 獲取 nodeName 和 ndoeType
console.log(p.nodeName);
console.log(p.nodeType);
Attribute
var pList = document.querySelectorAll('p');
var p = pList[0];
p.getAttribute('data-name');
p.getAttribute('data-name','imooc');
p.getAttribute('style');
p.setAttribute('style','font-size:30px;');
04-04
DOM結構操作
- 新增節點
var div1 = document.getElementById('div1');
//添加新節點
var p1 = document.createElement('p');
p1.innerHTML = 'this is p1';
div1.appendChild(p1); //添加新創建的元素
//移除已有節點
var p2 = document.getElementById('p2');
div1.appendChild(p2);
- 獲取父元素-獲取子節點
var div1 = document.getElementById('div1');
var parent = div1.parentElement;
- 刪除節點
var div1 = document.getElementById('div1');
var child = div1.childNodes;
div1.removeChild(child[0]);
舉個栗子(例子:example)?。。?/h4>
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="div1">
<p id="p1">this is p1</p>
<p id="p2">this is p2</p>
</div>
<div id="div2">
<p id="p3">this is p3</p>
<p id="p4">this is p4</p>
</div>
<script type="text/javascript">
// 1.
// var p = document.createElement('p');
// p.innerHTML = 'new p';
// var div1 = document.getElementById('div1');
// div1.appendChild(p);
// 2.移動P4到div1中
var p4 = document.getElementById('p4');
var div1 = document.getElementById('div1');
div1.appendChild(p4);
console.log(p4.parentElement);
console.log(div1.parentElement);
console.log(div1.childNodes);
console.log(div1.childNodes[0].nodeType); //text 3
console.log(div1.childNodes[1].nodeType); //p 1
</script>
</body>
</html>
04-05
DOM知識解答
- DOM是哪種基本的數據結構?
- 樹
- DOM操作的常用API有哪些
- 獲取DOM節點,以及節點的
property
和Attribute
- 獲取父節點,獲取子節點
- 新增節點,刪除節點
-
DOM節點
的Attribute
和property
有何區別
-
property
只是一個JS對象
的屬性的修改
-
Attribute
是對html標簽
屬性的修改
- 重點總結
- DOM本質
- DOM節點的操作
- DOM結構操作
04-06
BOM操作
- Browser Object Model
如何監測瀏覽器的類型
拆解url的各部分
知識點
navigator & screen
//navigator
var ua = navigator.userAgent;
var isChrome = ua.indexOf('Chrome');
console.log(isChrome);
//screen
console.log(screen.width);
console.log(screen.height);
location & history
//location
console.log(location.href);
console.log(location.protocel);
console.log(location.pathname);
console.log(location.search);
console.log(location.hash);
//history
history.back();
history.forward();
05-01
編寫一個通用的事件監聽函數
描述事件冒泡流程
* DOM樹形結構
* 事件冒泡
* 阻止冒泡
* 冒泡的應用
對于一個無線下拉加載圖片的頁面,如何給每個圖片綁定事件
* 使用代理
* 知道代理的有點
通用事件綁定
var btn = document.getElementById('btn1');
btn.addEventListener('click',function (event) {
console.log('clicked');
})
function bindEvent(elem,type,fn) {
elem.addEventListener(type,fn);
}
var a = document.getElementById('link1')
bindEvent(a,'click',function(e){
e.preventDefault(); //阻止默認行為
alert('clicked');
});
- 關于IE低版本的兼容性
- IE低版本使用attachEvent綁定事件,和W3C標準不一樣
- IE低版本使用量非常少,很多網站早已不支持
- 建議對IE低版本的兼容性:了解即可,無需深究
- 如果遇到對IE低版本要求苛刻的面試,果斷放棄
事件冒泡
<body>
<div id="div1">
<p id="p1">激活</p>
<p id="p2">取消</p>
<p id="p3">取消</p>
<p id="p4">取消</p>
</div>
<div id="div2">
<p id="p5">取消</p>
<p id="p6">取消</p>
</div>
</body>
var p1 = document.getElementById('p1');
var body = document.body;
bindEvent(p1,'click',function (e) {
e.stopPropatation();
alert('激活');
});
bindEvent(body,'click',function(e){
alert('取消');
})
代理
<div id="div1">
<a href="#">a1</a>
<a href="#">a2</a>
<a href="#">a3</a>
<a href="#">a4</a>
<!-- 會隨時新增更多a標簽 -->
</div>
var div1 = document.getElementById('div1');
div1.addEventListener('click',function (e) {
var target = e.target;
if (target.nodeName === 'A') {
alert(target.innerHTML);
}
})
完善通用綁定事件的函數
//使用代理
var div1 = document.getElementById('div1');
bindEvent(div1,'click','a',function (e) {
console.log(this.innerHTML);
})
function bindEvent(elem,type,selector,fn) {
if (fn == null) {
fn = selector;
}
elem.addEventListener(type,function (e) {
var target;
if (selector) {
target = e.target;
if (target.matches(selector)) {
fn.call(target,e);
}
}else {
fn(e);
}
})
}
05-02
Ajax-XMLHttpRequest
- 手動編寫一個ajax,不依賴第三方庫
- 跨域的幾種實現方式
知識點
XMLHttpRequest
var xhr = new XMLHttpRequest();
xhr.open("GET","/api",false)
xhr.onreadystatechange = function () {
//這里的函數異步執行,可參考之前JS基礎的異步模塊
if(xhr.readyState == 4){
if (xhr.status == 200) {
alert(xhr.responseText)
}
}
}
xhr.send(null);
* IE低版本使用ActiveXObject,和W3C標準不一樣
* IE低版本使用量已經非常少,很多網站早已不支持IE低版本
* 建議對IE低版本的兼容性:了解即可,無需深究
狀態碼
xhr.onreadystatechange = function () {
//這里的函數異步執行,可參考之前JS基礎的異步模塊
if(xhr.readyState == 4){
if (xhr.status == 200) {
alert(xhr.responseText)
}
}
}
- readyState
- 0-(未初始化)還沒有調用send()方法
- 1-(載入)已調用send()方法,正在發送請求
- 2-(載入完成)send()方法執行完成,已經接收到全部響應內容
- 3-(交互)正在解析響應內容
- 4-(完成)響應內容解析完成,可以在客戶端調用
- status
- 2XX-表示成功處理請求。如200
- 3XX-需要重定向,瀏覽器直接跳轉
- 4XX-客戶端請求錯誤,如404
- 5XX-服務端錯誤
跨域
- 什么時跨域
- 瀏覽器有同源策略,不允許ajax訪問其他域接口
- http://www.yourname.com/page1.html
- http://m.imooc.com/course/ajaxcourserecom?cid=459
- 跨域條件:協議、域名、端口、有一個不同就算跨域
- 但是有三個標簽允許跨域加載資源
<img src=XXX>
<link href=XXXX>
<script src=XXX>
- 三個標簽的場景
- <img>用于打點統計,統計網站可能是其他域
- <link><script>可以使用CDN,CDN的也是其他域
- <script>可以用于JSONP
- 跨域注意事項
- 所有的跨域請求都必須經過信息提供方允許
- 如果未經允許即可獲得,那是瀏覽器同源策略出現漏洞
- JSONP
不一定服務器端真正有一個classindex.html
文件
服務器可以根據請求,動態生成一個文件,返回
同理與<script src="http://coding.m.imooc.com/api.js">
假如你的網站要跨域訪問慕課網的一個接口
返回內容格式如callback({x:100,y:200})(可動態生成)
<script>
window.callback = function (data) {
//這是我們跨域的到信息
console.log(data);
}
</script>
<script src="http://coding.m.imooc.com/api.js"></script>
<!-- 以上將返回 callback({x:100,y:200}) -->
- 服務器端設置http header
- 另外一個解決跨域的簡潔方法,需要服務器來做
- 但是作為交互方,我們必須知道這個方法
- 是將來解決跨域問題的一個趨勢
//注意:不同后端語言的寫法可能不一樣
//第二個參數填寫允許跨域的域名稱,不建議直接寫 “*”
response.setHeader("Access-Control-Allow-Origin","http://a.com, http://b.com");
response.setHeader("Access-Control-Allow-Header","X-Requested-With");
response.setHeader("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
//接收跨域的cookie
response.setHeader("Access-Control-Allow-Credentials","true");
05-03
存儲
- 請描述一下
cookie
,sessionStorage
和localStorage
的區別?
cookie
- 本身用于客戶端和服務端通信
- 但是它有本地存儲的功能,于是就被
借用
- 使用document.cookie = ... 獲取和修改即可
cookie用于存儲的缺點
- 存儲量小,只有4kb
- 所有http請求都帶著,會影響獲取資源的效率
- API簡單,需要封裝才能用document.cookie = ...
localStorage和sessionStorage
- HTML5專門為存儲設計,最大容量5M
- API簡答易用:
- localStorage.setItem(key,value);localStorage.getItem(key);
- sessionStorage關閉瀏覽器會清理
- iOS safari 隱藏模式下,localStorage.getItem會報錯
- 建議統一使用try-catch封裝
cookie sessionStorage localStorage 的區別
- 容量
- 是否會攜帶到ajax中
- API易用性
06-01
模塊化
- 不使用模塊化
- 使用模塊化
- AMD
- CommonJS
不使用模塊化
util getFormatDate函數
a-util.js aGetFormatDate函數 使用getFormatDate
a.js aGetFormatDate
- 定義
//util.js
function getFormatDate(date,type) {
//type === 1返回 2017-06-15
//type === 2返回 2017年6月15日 格式
//...
}
//a-util.js
function aGetFormatDate(data) {
//返回
return getFormatDate(date,2);
}
// a.js
var dt = new Date()
console.log(aGetFormatDate(dt));
- 使用
<script src="util.js"></script>
<script src="a-util.js"></script>
<script src="a.js"></script>
<!-- 1.這些代碼中的函數必須是全局變量,才能暴露給使用方。全局變量污染 -->
<!-- 2. a.js 知道要引用 a-util.js ,但是他知道還需要依賴于util.js嗎? -->
使用模塊化
//util.js
export{
getFormatDate:function (data,type) {
//type === 1 返回 2017-06-15
//type === 2 返回 2017年6月15日 格式
}
}
//a-util.js
var getFormatDate = require('util.js');
export{
aGetFormatDate:function (date) {
//要求返回 2017年6月15日 格式
return getFormatDate(date,2);
}
}
// a.js
var aGetFormatDate = require('a-util.js')
var dt = new Date();
console.log(aGetFormatDate(dt));
//直接‘<script src="a.js"></script>’,其他的根據依賴關系自動引用
//那兩個函數,沒必要做成全局變量,不會帶來污染和覆蓋
06-02
AMD
- require.js
requirejs.org/
- 全局define函數
- 全局require函數
- 依賴JS會自動、異步加載
//util.js
define(function () {
return{
getFormatDate: function (date,type) {
if (type === 1) {
return '2017-06-15'
}
if (type === 2) {
return '2017年6月15日'
}
}
}
});
//a-util.js
define(['./util.js'],function (util) {
return{
aGetFormatDate: function (date) {
return util.getFormatDate(date,2);
}
}
});
// a.js
define('[./a-util.js]',function (aUtil) {
return{
printDate:function (date) {
console.log(aUtil.aGetFormatDate);
}
}
});
//main.js
require('[./a.js]',function (a) {
var date = new Date();
a.printDate(date);
});
- 使用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Document</title>
</head>
<body>
<p>AMD test</p>
<script src="/require.min.js" data-main="./main.js"></script>
</body>
</html>
06-03
CommonJS
- nodejs模塊化規范,現在被大量用于前端,原因:
- 前端開發依賴的插件和庫,都可以從npm中獲取
- 構建工具的高度自動化,是的使用npm的成本非常低
- CommonJS不會異步加載JS,而是同步一次性加載出來
module.exports = {
getFormatDate:function (data,type) {
if (type === 1) {
return '2017-06-15';
}
if (type === 2) {
return '2017年6月15日';
}
}
}
// a-util.js
var util = require('util.js')
module.exports = {
aGetFormatDate:function (data) {
return util.getFormatDate(data,2);
}
}
AMD和CommonJS的使用場景
- 需要異步加載JS,使用AMD
- 使用了npm之后建議使用CommonJS
07-01
上線回滾-上線回滾流程
- 上線和回滾的基本流程
- linux基本命令
上線回滾流程
- 重要的開發環節
上線流程要點
- 將測試完的代碼提交到git版本庫的master分支
- 將當前服務器的代碼全部打包并記錄版本號,備份
- 將master分支的代碼提交覆蓋到線上服務器,生成新的版本號
回滾流程要點
- 將當前服務器的代碼打包并記錄版本號,備份
- 將備份的上一個版本號解壓,覆蓋到線上服務器,并生成新的版本號
Linux基本命令
- 服務器使用Linux居多,server版,只有命令行
- 測試環境要匹配線上環境,因此也是Linux
- 經常需要登陸測試機來自己配置、獲取數據
08-01
JavaScript算法測試函數
- SetData()函數生成了存儲在數組中的隨機數字。Math類的random()函數會生成[0,1)區間內的隨機數字。換句話說,random()函數生成的隨機數字大于等于0,但不會等于1。最后在用Math類的floor()函數確定最終結果。
- 如下這個公式可以成功生成1~100的隨機數字集合。
function CArray(numElements) {
this.dataStore = [];
this.pos = 0;
this.numElements = numElements;
this.insert = insert;
this.toString = toString;
this.clear = clear;
this.setData = setData;
this.swap = swap;
for (var i = 0; i < numElements; ++i) {
this.dataStore[i] = i;
}
}
//數據輸出
function setData() {
for (var i = 0; i < this.numElements; ++i) {
this.dataStore[i] = Math.floor(Math.random() * (this.numElements + 1));//生成隨機數組
}
}
function clear() {
for (var i = 0; i < this.dataStore.length; ++i) {
this.dataStore[i] = 0;
}
}
function insert(element) {
this.dataStore[this.pos++] = element;
}
function toString() {
var restr = "";
for (var i = 0; i < this.dataStore.length; ++i) {
restr += this.dataStore[i] + " ";
if (i > 0 & i % 10 == 0) {
restr += "\n";
}
}
return restr;
}
function swap(arr,index1,index2) {
var temp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = temp;
}
//測試
var numElements = 100;
var myNums = new CArray(numElements);
myNums.setData();
console.log(myNums.toString());
<p align="center"><!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="div1">
<p id="p1">this is p1</p>
<p id="p2">this is p2</p>
</div>
<div id="div2">
<p id="p3">this is p3</p>
<p id="p4">this is p4</p>
</div>
<script type="text/javascript">
// 1.
// var p = document.createElement('p');
// p.innerHTML = 'new p';
// var div1 = document.getElementById('div1');
// div1.appendChild(p);
// 2.移動P4到div1中
var p4 = document.getElementById('p4');
var div1 = document.getElementById('div1');
div1.appendChild(p4);
console.log(p4.parentElement);
console.log(div1.parentElement);
console.log(div1.childNodes);
console.log(div1.childNodes[0].nodeType); //text 3
console.log(div1.childNodes[1].nodeType); //p 1
</script>
</body>
</html>
- 樹
- 獲取DOM節點,以及節點的
property
和Attribute
- 獲取父節點,獲取子節點
- 新增節點,刪除節點
DOM節點
的Attribute
和property
有何區別
-
property
只是一個JS對象
的屬性的修改 -
Attribute
是對html標簽
屬性的修改
- DOM本質
- DOM節點的操作
- DOM結構操作
navigator & screen
//navigator
var ua = navigator.userAgent;
var isChrome = ua.indexOf('Chrome');
console.log(isChrome);
//screen
console.log(screen.width);
console.log(screen.height);
location & history
//location
console.log(location.href);
console.log(location.protocel);
console.log(location.pathname);
console.log(location.search);
console.log(location.hash);
//history
history.back();
history.forward();
* DOM樹形結構
* 事件冒泡
* 阻止冒泡
* 冒泡的應用
* 使用代理
* 知道代理的有點
var btn = document.getElementById('btn1');
btn.addEventListener('click',function (event) {
console.log('clicked');
})
function bindEvent(elem,type,fn) {
elem.addEventListener(type,fn);
}
var a = document.getElementById('link1')
bindEvent(a,'click',function(e){
e.preventDefault(); //阻止默認行為
alert('clicked');
});
- IE低版本使用attachEvent綁定事件,和W3C標準不一樣
- IE低版本使用量非常少,很多網站早已不支持
- 建議對IE低版本的兼容性:了解即可,無需深究
- 如果遇到對IE低版本要求苛刻的面試,果斷放棄
<body>
<div id="div1">
<p id="p1">激活</p>
<p id="p2">取消</p>
<p id="p3">取消</p>
<p id="p4">取消</p>
</div>
<div id="div2">
<p id="p5">取消</p>
<p id="p6">取消</p>
</div>
</body>
var p1 = document.getElementById('p1');
var body = document.body;
bindEvent(p1,'click',function (e) {
e.stopPropatation();
alert('激活');
});
bindEvent(body,'click',function(e){
alert('取消');
})
<div id="div1">
<a href="#">a1</a>
<a href="#">a2</a>
<a href="#">a3</a>
<a href="#">a4</a>
<!-- 會隨時新增更多a標簽 -->
</div>
var div1 = document.getElementById('div1');
div1.addEventListener('click',function (e) {
var target = e.target;
if (target.nodeName === 'A') {
alert(target.innerHTML);
}
})
//使用代理
var div1 = document.getElementById('div1');
bindEvent(div1,'click','a',function (e) {
console.log(this.innerHTML);
})
function bindEvent(elem,type,selector,fn) {
if (fn == null) {
fn = selector;
}
elem.addEventListener(type,function (e) {
var target;
if (selector) {
target = e.target;
if (target.matches(selector)) {
fn.call(target,e);
}
}else {
fn(e);
}
})
}
var xhr = new XMLHttpRequest();
xhr.open("GET","/api",false)
xhr.onreadystatechange = function () {
//這里的函數異步執行,可參考之前JS基礎的異步模塊
if(xhr.readyState == 4){
if (xhr.status == 200) {
alert(xhr.responseText)
}
}
}
xhr.send(null);
* IE低版本使用ActiveXObject,和W3C標準不一樣
* IE低版本使用量已經非常少,很多網站早已不支持IE低版本
* 建議對IE低版本的兼容性:了解即可,無需深究
xhr.onreadystatechange = function () {
//這里的函數異步執行,可參考之前JS基礎的異步模塊
if(xhr.readyState == 4){
if (xhr.status == 200) {
alert(xhr.responseText)
}
}
}
- 0-(未初始化)還沒有調用send()方法
- 1-(載入)已調用send()方法,正在發送請求
- 2-(載入完成)send()方法執行完成,已經接收到全部響應內容
- 3-(交互)正在解析響應內容
- 4-(完成)響應內容解析完成,可以在客戶端調用
- 2XX-表示成功處理請求。如200
- 3XX-需要重定向,瀏覽器直接跳轉
- 4XX-客戶端請求錯誤,如404
- 5XX-服務端錯誤
- 瀏覽器有同源策略,不允許ajax訪問其他域接口
- http://www.yourname.com/page1.html
- http://m.imooc.com/course/ajaxcourserecom?cid=459
- 跨域條件:協議、域名、端口、有一個不同就算跨域
- 但是有三個標簽允許跨域加載資源
<img src=XXX>
<link href=XXXX>
<script src=XXX>
- 三個標簽的場景
- <img>用于打點統計,統計網站可能是其他域
- <link><script>可以使用CDN,CDN的也是其他域
- <script>可以用于JSONP
- 跨域注意事項
- 所有的跨域請求都必須經過信息提供方允許
- 如果未經允許即可獲得,那是瀏覽器同源策略出現漏洞
不一定服務器端真正有一個
classindex.html
文件服務器可以根據請求,動態生成一個文件,返回
同理與<script src="http://coding.m.imooc.com/api.js">
假如你的網站要跨域訪問慕課網的一個接口
返回內容格式如callback({x:100,y:200})(可動態生成)
<script>
window.callback = function (data) {
//這是我們跨域的到信息
console.log(data);
}
</script>
<script src="http://coding.m.imooc.com/api.js"></script>
<!-- 以上將返回 callback({x:100,y:200}) -->
- 另外一個解決跨域的簡潔方法,需要服務器來做
- 但是作為交互方,我們必須知道這個方法
- 是將來解決跨域問題的一個趨勢
//注意:不同后端語言的寫法可能不一樣
//第二個參數填寫允許跨域的域名稱,不建議直接寫 “*”
response.setHeader("Access-Control-Allow-Origin","http://a.com, http://b.com");
response.setHeader("Access-Control-Allow-Header","X-Requested-With");
response.setHeader("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
//接收跨域的cookie
response.setHeader("Access-Control-Allow-Credentials","true");
cookie
,sessionStorage
和localStorage
的區別?借用
util getFormatDate函數
a-util.js aGetFormatDate函數 使用getFormatDate
a.js aGetFormatDate
//util.js
function getFormatDate(date,type) {
//type === 1返回 2017-06-15
//type === 2返回 2017年6月15日 格式
//...
}
//a-util.js
function aGetFormatDate(data) {
//返回
return getFormatDate(date,2);
}
// a.js
var dt = new Date()
console.log(aGetFormatDate(dt));
<script src="util.js"></script>
<script src="a-util.js"></script>
<script src="a.js"></script>
<!-- 1.這些代碼中的函數必須是全局變量,才能暴露給使用方。全局變量污染 -->
<!-- 2. a.js 知道要引用 a-util.js ,但是他知道還需要依賴于util.js嗎? -->
//util.js
export{
getFormatDate:function (data,type) {
//type === 1 返回 2017-06-15
//type === 2 返回 2017年6月15日 格式
}
}
//a-util.js
var getFormatDate = require('util.js');
export{
aGetFormatDate:function (date) {
//要求返回 2017年6月15日 格式
return getFormatDate(date,2);
}
}
// a.js
var aGetFormatDate = require('a-util.js')
var dt = new Date();
console.log(aGetFormatDate(dt));
//直接‘<script src="a.js"></script>’,其他的根據依賴關系自動引用
//那兩個函數,沒必要做成全局變量,不會帶來污染和覆蓋
requirejs.org/
//util.js
define(function () {
return{
getFormatDate: function (date,type) {
if (type === 1) {
return '2017-06-15'
}
if (type === 2) {
return '2017年6月15日'
}
}
}
});
//a-util.js
define(['./util.js'],function (util) {
return{
aGetFormatDate: function (date) {
return util.getFormatDate(date,2);
}
}
});
// a.js
define('[./a-util.js]',function (aUtil) {
return{
printDate:function (date) {
console.log(aUtil.aGetFormatDate);
}
}
});
//main.js
require('[./a.js]',function (a) {
var date = new Date();
a.printDate(date);
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Document</title>
</head>
<body>
<p>AMD test</p>
<script src="/require.min.js" data-main="./main.js"></script>
</body>
</html>
- 前端開發依賴的插件和庫,都可以從npm中獲取
- 構建工具的高度自動化,是的使用npm的成本非常低
- CommonJS不會異步加載JS,而是同步一次性加載出來
module.exports = {
getFormatDate:function (data,type) {
if (type === 1) {
return '2017-06-15';
}
if (type === 2) {
return '2017年6月15日';
}
}
}
// a-util.js
var util = require('util.js')
module.exports = {
aGetFormatDate:function (data) {
return util.getFormatDate(data,2);
}
}
function CArray(numElements) {
this.dataStore = [];
this.pos = 0;
this.numElements = numElements;
this.insert = insert;
this.toString = toString;
this.clear = clear;
this.setData = setData;
this.swap = swap;
for (var i = 0; i < numElements; ++i) {
this.dataStore[i] = i;
}
}
//數據輸出
function setData() {
for (var i = 0; i < this.numElements; ++i) {
this.dataStore[i] = Math.floor(Math.random() * (this.numElements + 1));//生成隨機數組
}
}
function clear() {
for (var i = 0; i < this.dataStore.length; ++i) {
this.dataStore[i] = 0;
}
}
function insert(element) {
this.dataStore[this.pos++] = element;
}
function toString() {
var restr = "";
for (var i = 0; i < this.dataStore.length; ++i) {
restr += this.dataStore[i] + " ";
if (i > 0 & i % 10 == 0) {
restr += "\n";
}
}
return restr;
}
function swap(arr,index1,index2) {
var temp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = temp;
}
//測試
var numElements = 100;
var myNums = new CArray(numElements);
myNums.setData();
console.log(myNums.toString());
</p>
名詞解釋:
- n: 數據規模
- k:“桶”的個數
- In-place: 占用常數內存,不占用額外內存
- Out-place: 占用額外內存
- 穩定性:排序后2個相等鍵值的順序和排序之前它們的順序相同
08-02
JavaScript算法-冒泡排序
- 冒泡排序
- 最慢的排序算法之一
- 冒泡排序,之所以這么叫是因為使用這種排序算法排序時,數據值就會像氣泡一樣從數組的一端漂浮到另一端。假設正在將一組數字按照升序排列,較大的值會浮動到數組的右側,而較小的值會浮動到數組的左側。之所以會產生這種現象是因為算法會多次在數組中移動,比較相鄰的數據,當左側值大于右側值時將它們進行互換。
</p>
function bubbleSort() {
var numElements = this.dataStore.length;
var temp;
for (var outer = numElements; outer >= 2; --outer) {
for (var inner = 0; inner <= outer - 1; ++inner ) {
if (this.dataStore[inner] > this.dataStore[inner + 1]) {
swap(this.dataStore,inner,inner + 1);
}
}
}
}
- 使用bubbleSort()對10個數字排序
var numElements = 10;
var mynums = new CArray(numElements);
mynums.setData();
console.log(mynums.toString());
mynums.bubbleSort();
console.log(mynums.toString);
08-03
JavaScript算法-選擇排序
選擇排序
選擇排序從數組的開頭開始,將第一個元素和其他元素進行比較。檢查完所有元素后,最小的元素會被放到數組的第一個位置,然后算法會從第二個位置繼續。這個過程一直進行,當進行到數組的倒數第二個位置時,所有的數據便完成了排序。
選擇排序會用到嵌套循環。外循環從數組的第一個元素一定到倒數第二個元素;內循環從第二個數組元素移動到最后一個元素,查找比當前外循環
</p>
09-01
JS基本應用-函數
- 函數聲明與函數表達式、對象實例化的區別
add1(1,1);
add2(1,2);
add3(1,3);
function add1(i, j){
console.log(i+j);
}
var add2 = function(i, j){
console.log(i+j);
}
var add3 = new Function("i", "j", "console.log(i+j);");
- 對象實例化與函數聲明與函數表達式的區別
(function(){
var i = 10;
function add(j) {
console.log(i+j);
debugger;
}
add(1);
})();
(function(){
var i = 10;
var add = new Function("j", "console.log(i+j);debugger;");
add(1);
})();
- bind的使用
function Point(x, y){
this.x = x;
this.y = y;
}
Point.prototype.move = function(x, y) {
this.x += x;
this.y += y;
}
var p = new Point(0,0);
var circle = {x:1, y:1, r:1};
var circleMove = p.move.bind(circle, 2, 1);
circleMove();
- 構造函數
function Car(type,color){
this.type = type;
this.color = color;
this.status = "stop";
this.light = "off";
}
Car.prototype.start = function(){
this.status = "driving";
this.light = "on";
console.log(this.type + " is " + this.status);
}
Car.prototype.stop = function(){
this.status = "stop";
this.light = "off";
console.log(this.type + " is " + this.status);
}
var audi = new Car("audi", "silver");
var benz = new Car("benz", "black");
var ferrari = new Car("ferrari", "yellow");
- 函數調用模式
function add(i, j){
return i+j;
}
var myNumber = {
value: 1,
double: function(){
var helper = function(){
this.value = add(this.value,this.value);
}
helper();
}
}
- arguments轉數組
function add(i, j) {
var args = Array.prototype.slice.apply(arguments);
args.forEach(function(item){
console.log(item);
})
}
add(1,2,3);
- arguments.callee使用
console.log(
(function(i){
if (i==0) {
return 1;
}
return i*arguments.callee(i-1);
})(5)
);
- 遞歸
function factorial(i){
if (i==0) {
return 1;
}
return i*factorial(i-1);
}
- 普通遞歸函數跟記憶函數調用次數對比
var factorial = (function(){
var count = 0;
var fac = function(i){
count++;
if (i==0) {
console.log('調用次數:' + count);
return 1;
}
return i*factorial(i-1);
}
return fac;
})();
for(var i=0;i<=10;i++){
console.log(factorial(i));
}
//記憶函數
var factorial = (function(){
var memo = [1];
var count = 0;
var fac = function(i){
count++;
var result = memo[i];
if(typeof result === 'number'){
console.log('調用次數:' + count);
return result;
}
result = i*fac(i-1);
memo[i] = result;
return result;
}
return fac;
})();
for(var i=0;i<=10;i++){
console.log(factorial(i));
}
- curry 函數柯里化
- 把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,并且返回接受余下的參數而且返回結果的新函數的技術
function add(value){
var helper = function(next){
value = typeof(value)==="undefined"?next:value+next;
return helper;
}
helper.valueOf = function(){
return value;
}
return helper
}
JSDemo JS小程序
JDMenu 京東無延遲菜單
1.開發普通二級菜單
- 事件代理方式進行綁定
-
mouseenter
和mouseover
的區別: - 使用
mouseover/mouseout
時候,如果鼠標移動到子元素上,即便沒有離開父元素,也會觸發父元素的mouseout
事件; - 使用
mouseenter/mouseleave
時,如果鼠標沒有離開父元素,在其子元素上任意移動,也不會觸發mouseleave
事件;
2.加入延遲優化
- 切換子菜單的時候,用
setTimeout
設置延遲 -
debounce
去抖o((⊙﹏⊙))o.技術: - 在事件被頻繁觸發時買只執行一次
3.基于用戶行為預測的切換技術
- 跟蹤鼠標的移動
- 用鼠標當前位置,和鼠標上一次位置與子菜單上下邊緣形成的三角區域進行比較
DatePicker組件開發
1.基礎頁面制作
- 標頭
- 身體
2.數據部分
- 渲染當月日歷表格
- 用于點擊時取日期值
日期對象
newDate(year,month-1,date)
- 月份需要-1
- 越界自動進退位
getFullYear()/getMonth()/getDate()
-
getDay()
獲取當前日期是周幾?
轉自github