(一)js基础-原型链
创建对象的几种方法
- 1)字面量
var o1 = {name:'aa'};
- 2)使用new Object()
var o2 = new Object({name:'bb'})
- 3)使用显示的构造函数
var O = function(name){ this.name = name}
var o3 = new O("cc");
- 4)使用Objec.create方法创建
var P= {name:'dd'}
var o4 = Object.create(P);
原型、构造函数、实例、原型链
- 1) 原型
- 2) 构造函数:使用new操作的函数为构造函数
- 3) 实例:只要是对象即为一个实例
构造函数使用new生成一个实例
函数均有一个prototype属性(对象没有),声明函数时js自动加上,prototype即为原型对象,为区分原型对象是被哪一个构造函数所引用,使用constructor指向默认的构造函数。
只有实例对象有__proto__属性
实例的__proto__属性为构造函数的原型对象
原型链
var M = function(name){ this.name = name}
var o3 = new M();
M.prototype.say = function(){
console.log("say hi");
}
var o4 = new M('o4');
o3.say(); //say hi
o4.say(); //say hi
M.__proto__ === Function.prototype //true
instanceof的原理
instanceof(判断实例对象是否为构造函数的实例)的原理是判断实例对象的__proto__属性与构造函数的prototype是否为同一引用地址。
var M = function(name){ this.name = name}
var o3 = new M();
o3 instanceof M; //true
o3 instanceof Object; //true 在同一原型链上
o3.__proto__ === M.prototype; //true
M.prototype.__proto__ === Object.prototype; // true
//故使用constructor判断实例对象是否为某一构造函数的实例
o3.__proto__.constructor === M; //true
o3.__proto__.constructor === Object; //false
new运算符
-
1、一个新的对象被创建,继承自构造函数foo.prototype。
-
2、构造函数foo被执行,执行时,相应的传参会被传入,同时上下文(this)会别指定为新实例
-
3、如果构造函数返回了一个“对象”,那么这个对象会取代整个new出来的结果。如果构造函数没有返回对象,那么new出来的结果为步骤1创建的对象。
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; //true
o6 instanceof Object; //true
o6.__proto__.constructor === M ; //true
M.prototype.walk = function(){
console.log('walk');
}
o6.walk(); //walk
先使用new Object()建一个空对象obj,设置新对象的constructor属性为构造函数的名称,设置新对象的__proto__属性指向构造函数的prototype对象,然后使用新对象调用函数,函数中的this被指向新实例对象,将初始化完毕的新对象地址,保存到等号左边的变量中。
//创建空对象
new obj = {};
//让Person中的this指向obj,并执行person的函数体
var result = Person.call(obj);
//完成原型链的构建
obj.__proto__ = Person.prototype;
// 判断Person的返回值类型,如果是值类型则返回obj,如果是引用类型,就返回这个引用类型的对象。
if(typeof(result) === 'object'){
person = result;
}
else {
person = obj;
}