1. 原型链
原型链描述了实例对象和构造函数的关系,每个实例对象obj都包含一个__proto__属性,每个构造函数Class都有一个prototype原型对象,两者的关系是obj.__proto__===Class.prototype
,而构造函数的原型和构造函数的关系是Class.prototype.constructor===Class
instanceof就是按照上图,从左侧的__proto__向上查找,从右侧的prototype向下查找判断是否指向同一个终点
2. new操作符
function User(name , age) {
this.name = name
this.age = age
}
User.prototype.sayHi= function () {
console.log("Hello")
}
let user=new User('a',10)
通过这种方式的实例user具有User的属性和原型方法,在new的过程中,所执行的操作包括
- 开辟内存给一个空对象:
let user={}
- 将原型上的属性和方法传递给实例:
user.__proto__=User.prototype
- 将构造函数上的属性和方法传递给实例:
User.apply(user,['a',10])
根据以上理解,修改以下例子:
function newUser(name , age,) {
return {
name,
age,
}
}
newUser.prototype.sayHi = function () {
console.log("Hello")
}
let user=newUser('a',10)
此时的user只有构造函数上的name和age 属性,相当于只实现了new的第一步和第三步,希望user包括sayHi方法,则使用user.__proto__=newUser.prototype
手写一个new方法:
function newInstance(Parent,...params){
let child={}
Parent.call(child,...params)
child.__proto__=Parent.prototype
return child
}
var user=newInstance(User,'xiaomign',19)
console.log(user instanceof User) //true
3.类的继承
参考博客
(1)构造函数继承
使用call、apply实现
缺点:不能继承原型上的属性和方法
(2)原型继承
缺点:公用一套属性
(3)组合继承(常用)
组合(1)和(2)
(4)拷贝继承
把一个对象中的属性和方法直接复制到另一个对象中
(5)直接继承prototype
Child.prototype=Parent.prototype
缺点:引用传递,修改Child的属性Parent的属性也会改变