1、相关知识点
(1)构造函数 (函数名首字母大写表示构造函数)
1function Foo(name,age){ 2 this.name = name; 3 this.age = age; 4 this.class = 'class'; 5 //return this; 默认有这一行,浏览器帮忙做了 6} 7var f = new Foo('chenyan',25); 8 9// new 执行时,this先变成一个空对象,然后再Foo函数里给this赋值,最后返回this 10console.log(f instanceof Foo) 11// instanceof 判断函数Foo 是否是变量 f 的构造函数
(2)、构造函数——扩展
var a={} 其实是 var a = new Object()的语法糖;
var a=[] 其实是 var a = new Array() 的语法糖;
function Foo(){} 其实是 var Foo = new Function();
强烈推荐使用前者写法。
2、原型规则和示例
(1)、所有的引用类型(数组,对象,函数)都具有对象特性,即可自由扩展属性(null除外)
1var obj = {}; 2obj.a = 100; 3var arr = []; 4arr.a = 100; 5function fn() {}; 6fn.a = 100;
(2)、所有的引用类型(数组,对象,函数)都有一个_proto_(隐式原型)属性,属性值是一个普通对象(null除外)
1console.log(obj._proto_);//浏览器默认 2console.log(arr._proto_);//浏览器默认
(3)、所有的函数都有一个prototype属性(显式原型),属性值也是一个普通对象
console.log(fn.prototype);//浏览器默认
(4)、所有引用类型(数组,对象,函数)的_proto_属性值 指向它的构造函数的prototype属性值。
1console.log(obj._proto_ === Object.prototype); 2//Object 是 obj的构造函数
(5)、当试图得到一个对象(引用类型)的某个属性值时,如果这个对象本身没有这个属性,那么会去它的_proto_(即它的构造函数的prototype)中寻找
1//构造函数 2function Foo(name, age){ 3 this.name = name; 4 this.age = age; 5} 6Foo.prototype.alertName = function(){console.log(this.name)}; 7//创造实例 8var f = new Foo("chenyan",25); 9f.printAge = function(){console.log(this.age)}; 10//测试 11f.printAge(); 12f.alertName();//alertName() 不是 f 的自身属性,去 f 的构造函数的prototype 中找;f 继承了构造函数的属性
问题:如何去掉来自原型的属性?
1var item; 2for( item in f){ 3 //高级浏览器已经在for in 中屏蔽了来自原型的属性 4 //建议加上这个判断,保证程序健壮性 5 //hasOwnProperty 获取对象自身属性 6 if (f.hasOwnProperty(item)) { 7 console.log(item); 8 } 9}
3、原型链
f.toString() 去f._proto_(Foo.prototype)._proto_(Object) 中找

4、instanceof
用于判断引用类型属于 哪个构造函数的方法
1var arr=[]; 2console.log(arr instanceof Array);
f instanceof Foo 的判断逻辑:
f 的_proto_ 一层一层往上找,能否对应到Foo.prototype
再试着判断 f instanceof Object
5、一些题目
(1)、如何判断一个变量是数组类型
1var arr=[]; 2console.log(arr instanceof Array);//true 3console.log( tyopeof arr);// Objecct typeof无法判断是否是数组
(2)、写一个原型链继承的例子