//第一种方式:字面量 var o1 = {name:"o1"};//{name: "o1"} var o2 = new Object({name:"o2"});//{name: "o2"} //第二种方式:构造函数 var M = function(name){this.name = name;}; var o3 = new M("o3");//M {name: "o3"} //第三种方式:Object.create(o4.__proto__===p//true) var p = {name:"p"}; var o4 = Object.create(p);//{}
原理:ECMAScript中描述了原型链的概念,并将原型链做为实现继承的主要方法。其基本思想是利用原型让一个引用类型继承另外一个引用类型的属性和方法。在JavaScript中,用__proto__
属性来表示一个对象的原型链。html
任何一个函数,被new使用了,new后面的函数就是一个构造函数。构造函数能够经过new
运算符来生成一个实例。数组
在声明一个(构造)函数的时候,js引擎会自动给它加上一个prototype
属性,此属性会初始化一个空对象,即向原型对象。M.prototype.constructor===M;
返回true浏览器
原型对象怎么能区分是被哪个构造函数引用的呢?原型对象中有一个构造器(constructor
),默认的是声明的构造函数。o3.__proto__===M.prototype;
返回true函数
小提示:1.实例对象只有
__proto__
,没有prototype
属性。
2.构造函数有prototype
属性。(也有__proto__
,由于函数也是一个对象。M.__proto__===Function.prototype;
返回true。)测试
instanceof的原理:用来判断实例对象的__proto__
属性和构造函数的prototype
属性是否是同一个引用。/ 判断类(构造函数)的prototype
对象是否存在于实例对象的原型链上。是则返回true。this
o3 instanceof M;
返回true(o3.__proto__===M.prototype;
返回true)o3 instanceof Object;
返回true(M.prototype.__proto__===Object.prototype;
返回true)M instanceof Function;
返回true。M instanceof Object;
返回true。*使用 instanceof 判断 引用类型 属于哪一个 构造函数 的方法。spa
*判断一个对象是否为数组:arr instanceof Array
prototype
*判断一个对象的构造函数用constructor比较合理code
o3.__proto__.constructor===M;
//trueo3.__proto__.constructor===Object;
//falsefoo.prototype
)new
出来的结果为第一步建立的对象;若是构造函数返回了一个“对象”,那么这个对象会取代整个new
出来的结果。//模拟new运算符 var new2 = function(func){ var o =Object.create(func.prototype); //第一步 var k =func.call(o);//第二步 //第三步 if(typeof k ==="object"){ return k; }else{ return o; } } //验证 o6=new2(M)//建立一个新对象 o6 instanceof M//rue o6 instanceof Object//true o6.__proto__.constructor===M//true
obj.__proto__ === Object.prototype
//构造函数 function Foo(name,age){ this.name = name; } Foo.prototype.alertName = function(){ alert(this.name);//this是f } //建立实例 var f = new Foo('zhangsan'); f.printName = function(){ console.log(this.name);//this是f } //测试 f.printName(); f.alertName();
var item; for(item in f){ // 高级浏览器已经在 for in 中屏蔽了来自原型的属性 // 可是这里建议仍是加上这个判断,保证程序的健壮性 if(f.hasOwnProperty(item)){ console.log(item); } }
画出一下代码的原型链,便于理解。htm
//构造函数 function Foo(name,age){ this.name = name; this.age = age; //return this; // 默认有这一行 } var f = new Foo('zhangsan',21);
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); return this;//链式操做 } var div1 = new Elem('test'); div1.html('<p>hello world </P>').on('click',function(){console.log('clicked');})