构造函数模式知识的扩展
4.1、类中出现的this
1 function Fn() { 2 this.x = 100; 3 this.getX = function () { 4 // this-> 需要看getX执行的时候才知道 5 console.log(this.x); 6 }; 7 } 8 var f1 = new Fn; 9 f1.getX(); // 100 方法中的this是f1 10 11 var xx = f1.getX; 12 xx(); // undefined 方法中的this是window
在构造函数模式中创建对象new Fn(),如果Fn不需要传递参数的话,后面的小括号可以省略,即:new Fn
this的问题:在类中出现的this.xxx=xxx中的this都是当前类的实例,而类中某一个方法中的this需要看方法执行的时候,前面 是否有“."才能知道this是谁
4.2、私有变量
1 function Fn() { 2 var num = 10; 3 this.x = 100; // f1.x = 100 4 this.getX = function () { // f1.getX=function 5 console.log(this.x); 6 }; 7 } 8 var f1 = new Fn; 9 console.log(f1.num); // -> undefined
类有普通函数的一面,当函数执行的时候,var num其实只是当前形成的私有作用域中的私有变量而已,它和f1这个实例没有任何的关系,只有this.xxx=xxx才相当于给f1这个实例增加私有的属性和方法,才和f1有关系。
4.3、类中的return
1 function Fn() { 2 this.x = 100; 3 this.getX = function () { 4 console.log(this.x); 5 }; 6 // return 100; return {name:'iceman'}; 7 } 8 var f1 = new Fn; 9 console.log(f1);
在构造函数模式中,浏览器会默认的把我们的实例返回(返回的是一个对象数据类型的值),如果我们自己手动写了return返回:
返回的是一个基本数据类型的值:当前实例的值是不变的,例如:return 100,此时的f1还是当前Fn类的实例;
返回的是一个引用数据类型的值:当前的实例会被自己返回的实例给替换掉,例如:return {name:'icmean'},此时的f1就不是Fn的实例,而是返回的这个对象;
4.4、检测实例是否属于类
1 function Fn() { 2 this.x = 100; 3 this.getX = function () { 4 console.log(this.x); 5 }; 6 } 7 var f1 = new Fn; 8 console.log(f1 instanceof Fn); // --> true 9 console.log(f1 instanceof Array); // --> false 10 console.log(f1 instanceof Object); // --> true
检测某一个实例是否属于某一个类,使用的是instanceof,因为typeof只能检测基本数据类型的变量,有自己的局限性,不能细分Object下的对象、数组、正则...
所有的实例都是对象数据类型,而每一个对象数据类型的变量都是Object这个内置类的一个实例,所以f1也是Object的实例。
4.5、检测私有属性
1 function Fn() { 2 this.x = 100; 3 this.getX = function () { 4 console.log(this.x); 5 }; 6 } 7 var f1 = new Fn; 8 var f2 = new Fn;
f1和f2都是Fn这个类的实例,都拥有x和geX两个属性,但是这两个属性是各自的私有的属性,所以:
1 console.log(f1.getX === f2.getX); // --> false
in:检测某一个属性是否属于这个对象,attr in object,不管是私有的属性,还是公有的属性,只要存在,用in来检测都是true
1 console.log('getX' in f1); // --> true 是它的一个属性
hasOwnProperty:用来检测某一个属性是否为这个对象的私有属性,这个方法只能检测私有的属性
1 console.log(f1.hasOwnProperty('getX')); // --> true 'getX'是f1的私有属性
检测某一个属性是否为该对象的公有属性
1 function hasPubProperty(obj, attr) { 2 // 首先保证是它的一个属性,并且还不是私有的属性,那么只能是公有的属性了 3 return (attr in obj) && !obj.hasOwnProperty(attr); 4 } 5 console.log(hasPubProperty(f1, 'getX'));
02this
以上出现了很多次this,这里介绍下this。
在JavaScript中主要研究的都是函数中this,但是并不是只有函数中才有this,全局的this是window。
JavaScript中的this代表的是当前行为执行的主体,JavaScript中的context代表的是当前行为执行的环境。
首先明确:this是谁,和函数在哪里定义,在哪里执行都没有任何的关系,那么如何区分this呢?
-
函数执行,首先看函数名前面是否有".",有点话,"."前面是谁,this就是谁,没有的话,this就是window;
-
自执行函数中的this永远是window;
-
给元素的某一个事件绑定方法,当事件触发的时候,执行对应的方法,方法中的this是当前的元素。
-
1 function fn() { 2 console.log(this); 3 } 4 var obj = { 5 fn:fn 6 }; 7 fn(); // this -> window 8 obj.fn(); // this -> obj 9 10 document.getElementById('div1').onclick = fn; // fn中的this是#div1 11 document.getElementById('div1').onclick = function () { 12 // this -> #div1 13 fn(); // this -> window 14 };
1 function sum() { 2 // this -> window 3 fn();// this -> window 4 } 5 sum(); 6 var oo = { 7 sum:function () { 8 // this -> oo 9 fn(); // this -> window 10 } 11 }; 12 oo.sum();