1、JavaScript特色javascript
變量聲明php
1 var arr = [1,2,3]; 2 var num = 123; 3 var steing = "abc";
1 var num = 123; 2 var num; 3 num = 123;
1 var num1 = 123, 2 num2 = 234, 3 num3 = 456;
2.變量命名規則css
3.數據類型(值類型)html
4.默認爲false的值java
1 console.log(typeof(123)); // Number
2.Number(mix)[混合]es6
3.parseInt(string,radix)[基數]shell
1 parseInt('123abc123') // 123; 2 parseInt('abc123') // NaN; 3 parseInt('123') // 123; 4 parseInt('true') // NaN;
1 var demo = 10; 2 parseInt(demo,16) //16
4.parseFloat(radix)數組
1 parseFloat('123.2.3') // 123.2 2 parseFloat('132.2abc') // 123.2 3 parseFloat('123.abc1') // 123
5.toString(radix)瀏覽器
1 var demo = 123; 2 typeof demo.toString(); // string123; 3 typeof true.toString(); // stringtrue;
1 var dome = 10; 2 demo.toString(16) // A
6.String(mix)閉包
7.Boolean(mix)
1.isNaN()
2.算數運算符
3.邏輯運算符
4.不發生類型轉換的比較運算符
函數聲明提高:函數聲明提高是一種總體提高,他、它會把函數聲明和函數體一塊兒提到前面。
變量聲明提高:變量聲明提高是一種局部提高,它僅僅將變量的聲明提早了,可是並無將賦值一塊兒提高。
1.js運行三部曲
2.預編譯前奏
3.預編譯四步
1 function test (a,b) { 2 console.log(a) 3 function a () {} 4 a = 222; 5 console.log(a) 6 function b () {}; 7 console.log(b) 8 var b = 111; 9 var a; 10 } 11 test(1);
1.函數聲明有3種方式
1 var demo = function () {}; 函數表達式 2 function demo () {}; 函數聲明 3 var demo = function xxx () {};命名函數表達式 //沒用
1 function test(a,b) { 2 console.log(a + b); 3 return; 4 console.log('hello'); 5 } 6 test(1,2); // 打印結果3 不會打印hello
1 var demo = 123; // 全局變量 2 function test () { 3 var demo = 234; // 局部變量 4 console.log(demo); 5 var demo1 = 'hello'; 6 } 7 test(demo); // 打印234 就近打印局部變量,沒有局部變量打印全局變量 8 console.log(demo1); // 報錯 咱們的全局做用域沒法訪問局部做用域
1 function demo () { 2 var dome_a = 1; 3 function test () { 4 var demo_a = 2; 5 console.log(demo_a); 6 } 7 test(); 8 } 9 demo();
1.什麼是閉包
1 function a (){ 2 var dome1 = 123; 3 add = function(){ 4 demo1 ++; 5 } 6 return function(){ 7 console.log(demo1); 8 }; 9 } 10 var demo = a (); 11 demo(); // 123 12 add(); 13 demo(); // 124
2.使用閉包的注意點
1 var name = 'global'; 2 var obj = { 3 name:'obj', 4 getName:function() { 5 return function () { 6 console.log(this.name); 8 } 10 } 11 } 12 obj.getName() ();
1 function a () { 2 var num = 1; 3 function addNum () { 4 num ++; 5 console.log(num); 6 } 7 return addNum; 8 } 9 var demo = a (); 10 demo(); 11 demo(); 12 var demo1 = a(); 13 demo1(); 14 demo1();
1 (function (){}()) 2 function returnB() { 3 var arr = []; 4 for(i = 0; i < 10; i ++){ 5 arr[i] = (function(){ 6 console.log(i); 7 }()) 8 } 9 return arr; 10 } 11 var save = returnB(); 12 console.log(save); 13 for(j = 0; j < 10; j ++){ 14 save[j]; 15 }
1.對象的建立方式有三點
1 var obj ={};
2.構造函數【constructor】
1 var object = new object();
3.自定義構造函數
1 var function Person () {}; 2 var operson = new Person (); 3 typeof operson // object
1 function Person (name,age) { 2 this.name = name; 3 this.age = age; 4 } 5 var person = new Person('zhangsan',18); 6 console.log(person.name);
1 function Person (name) { 2 var this = {}; 3 this.name = name; 4 return this; 5 }
1 function Person (name) { 2 var that = { 3 name: 'lisi' 4 }; 5 that.name = name; 6 return that; 7 } 8 var person = new Person ('demo'); 9 console.log(person.name)
4.屬性的增刪改查
1 var obj = {};
2 obj.name = 'xiaoming'
1 var obj = { 2 name:'demo'; 3 } 4 obj.name = 'tan';
1 var obj = { 2 name = 'scerlett' 3 } 4 obj.name; // scerlett 5 delete obj.name; 6 obj.name; // undefined
1.原型的定義:原型是function對象的一個屬性,它定義了構造函數製造出來的對象的公有祖先,經過該構造函數產生的對象,能夠繼承原型的屬性和方法,原型也是對象。
1 function Person () {}
2.利用原型特色概念,能夠提取公有屬性
3.對象如何查看原型
4.如何查看構造自身的構造函數
1 console.log(person.constructor); //person();
1.有了原型,原型仍是一個對象,那麼這個名爲原型的對象天然還有本身的原型,這樣的原型上還有原型的結構就成了原型鏈。
1 Gra.prototype.firsName = 'scarlett' 2 function Gra () { 3 this.name = 'grandfather'; 4 this.sex = 'male'; 5 } 6 var grandfoo = new Gra(); 7 garndfoo.word = 'hello' 8 Foo.prototype = grandfoo; 9 function Foo () { 10 this.age = '18'; 11 this.money = '100'; 12 } 13 var father = new Foo(); 14 function Son () { 15 this.name = 'son'; 16 } 17 Son.prototype = father; 18 var son = new Son();
2.可是並非全部的對象都有原型,好比使用Object.create方法。
1 var obj = Object.create(Object.prototype);
3.原型鏈上的增刪改查
1 Person.prototype.arr[1,2,3]; 2 var person1 = new Person(); 3 var person2 = new Person(); 4 person1.arr.push(4); 5 console.log(person2);//1 2 3 4
1.this的一些問題:
函數內部的this默認指向window,可使用call / apply來改變this的指向,區別:後面傳參形式不一樣。
1 function person () { 2 this.name = 'scarlett'; 3 console.log(this); 4 } 5 person();
如今this指向window,name屬性天然就是window上的全局屬性
var obj = {}; person。call(object)//Object.{name:'scarlett'}
若是這個函數還有參數的話,只要把實參的值寫在call後面而且用逗號隔開
function person(name,age){ this.name = name; this.age = age; } var obj = {}; person.call(obj,'scarlett',18); console.log(obj.name);
apply和call基本沒什麼區別,惟一的區別就是call後面的參數是一個一個傳的,而apply後面的參數是放在數組裏
person.apply(obj['scarlett',18]);
2.繼承【inherit】
聖盃模式
function inherit(Target, Origin) { function F() {}; F.prototype = Origin.prototype; Target.prototype = new F(); Target.prototype.constuctor = Target;//讓constuctor指向本身的 Target.prototype.uber = Origin.prototype; //超類,知道本身繼承的是誰
yahu封裝方法:
1 // var inherit = (function (){ 2 // var F = function () {}; 3 // return function (Target, Origin){ 4 // F.prototype = Origin.prototype; 5 // Target.prototype = new F(); 6 // Target.prototype.constuctor = Target; 7 // Target.prototype.uber = Origin.prototype; 8 // } 9 // }()); 10 // 11 // for (var i = 0; i < 5; i ++) { 12 // var btn = document.createElement('button'); 13 // btn.appendChild(document.createTextNode('Button' + i)); 14 // btn.addEventListener('click', function(){console.log(i); }); 15 // document.body.appendChild(btn); 16 // }
對象的枚舉與this
1.對象的枚舉
查看對象的屬性能夠用obj.name查看,也能夠用obj['name']類數組方式查看,但事實上是數組模仿了對象的查看方式
2.for-in操做符
要枚舉一個數組的全部屬性只需用一個for循環從頭至尾遍歷一遍就能夠了。
可是對象並不能用for循環來遍歷屬性,全部就要用到for-in操做了
1 // var obj = { 2 // name: 'scarlett', 3 // age: 18, 4 // sex: 'female' 5 // } 6 // for(var prop in obj){ 7 // console.log(prop + ':' + obj[prop]); 8 // }
2.三種操做符
hasOwnProperty這個操做符的做用是查看當前這個屬性是否是對象自身的屬性,在原型鏈上的屬性會被過濾掉,自身的ture
// function Person() { // this.name = 'scarlett' // } // Person.prototype = { // age:18 // } // var oPerson = new Person(); // for (var prop in oPerson) { // if (oPerson.hasOwnProperty(prop)){ // console.log(oPerson[prop]); // } // }
這樣for-in循環就只會打印自身的屬性,而不是打印原型上的屬性
in操做符:這個操做符的做用是查看一個屬性是否是在這個對象或者它原型裏面。
1 // 'name' in oPerson; //ture 2 // 'sex' in oPerson; //False
instanceof操做符:做用是查看前面對象是否是後面的構造函數構造出來的,和constructor很像
1 // oPerson intanceof object; // ture 2 // {} instanceof oPerson; // false
3.this
1 // var obj = { 2 // height:190, 3 // eat:function () { 4 // this.height ++; // eat在沒有執行以前,誰也不知道this指向誰 5 // } 6 // } 7 // obj.eat(); // 誰調用this,this指向誰 8 // eat.call(obj); // eat裏面的this指向obj
若是能理解下面的這段代碼的this指向問題,那麼就掌握的this的全部知識點了
1 // var name = '222' 2 // var a = { 3 // name:'111', 4 // say:function () { 5 // console.log(this.name); 6 // } 7 // } 8 // var fun = a.say; 9 // fun(); // 此處其實就是把a.say這個函數體賦給fun這個函數,至關於在全局空間寫下了一個fun函數,此時this指向window,打印'222' 10 // a.say(); // 按照誰調用指向誰的說法,這裏打印'111' 11 // var b = { 12 // name:'333', 13 // say:function (fun) { 14 // fun(); 15 // } 16 // } 17 // b.say(a.say); // 其實和在全局調用a.say的函數體方法差很少,打印'222' 18 // b.say = a.say; 19 // b.say(); // this指向B 因此打印'333'
1.argument.callee
這個方法是指代函數自己,當在一些匿名函數或者當即執行函數裏面進行遞歸調用函數自己的時候,因爲沒有名字,就用這種方式調用;
通常當須要經過計算機進行初始化的時候,寫一個當即執行函數,當這個當即執行函數還須要遞歸調用自身的時候,就用這種方式調用。
2.function.caller
// function test () { // console.log(test.caller); // } // function demo () { // test() // } // demo();
這是函數自己自帶的一個屬性,能夠指出當前函數的ude運行環境的函數引用,就是這個函數在哪一個函數裏面執行的……
3.克隆【clone】
克隆和繼承有一些區別,克隆是複製出來如出一轍的目標對象又分爲淺度克隆和深度克隆
// function clone (src,tar) { // var tar = tar || {}; // for (var prop in src) { // if (src.hasOwnProperty(prop)){ // tar[prop] = src[prop]; // } // } // return tar; // }
當有一個屬性是引用值(數組、對象)時按照這種克隆模式,只是把這個引用值的指向賦給了新的目標對象,一旦改變了原對象或者目標對象的引用屬性另外一個也跟着變,這一點就是淺度克隆的缺點;
深度克隆的原理很簡單,只要不克隆引用值的引用而是把引用值也當作一個原對象,把裏面的值一個個克隆島目標對象裏面,就解決了兩者相同指向的問題;
// function deepCopy (src,tar) { // var tar = tar || {}; // for (var prop in src) { // if(typeof(src[prop] == 'object')){ // tar[prop] = (src[prop].constructor === Array) ? [] : {}; // }else{ // tar[prop] = src[prop]; // } // } // return tar; // }
這個時候目標對象和原對象的引用值就沒有關係了,都是獨立值能夠進行修改。
4.數組【array】