原型和原型链
1.构造函数
function Person(name, age){
this.name = name
this.age = age
return this // 默认会有这一行,不写也可以
}
let p1 = new Person('zhangsan',20)
let p2 = new Person('lisi', 21)
//类似于模板
//如何执行new的
/*
1.this变成空对象
2.赋值
3.return回来this
*/
构造函数-扩展
let a = {} // 其实就是 let a = new Object()
let b = [] // 其实就是 let b = new Array()
可以使用instanceof判断一个函数是否是一个变量的构造函数
var instanceof Array
推荐前面的书写方式
2.原型规则
//所有的引用类型都具有对象特性
2.1 可以自由扩展属性
let obj = {}
obj.a = 123
let arr = []
arr.b = 123
2.2 所有的引用类型,都有一个__proto__属性
let o = obj.__proto__
2.3 所有的函数都有一个prototype属性
console.log(Object.prototype)
console.log(Person.prototype)
2.4 new出来的对象称为实例,实例的__proto__ 指向其构造函数的prototype
console.log(obj.__proto__ === obj.constructor.prototype === Object.prototype)
2.5
当要得到一个对象的属性,如果这个对象本身没有这个属性,会去他的__proto__
也就是去它的构造函数的prototype中去找,这里可以一层一层的找
前面我们定义了Person()构造函数 其实这个函数也是Object的一个实例化
Object的prototype的属性将被用到
因此下列的代码成立
p1.toString()
因为可以一层一层的找,所以有了原型链
如果不能理解,可以考虑什么是实例
实例是构造函数创建出来的对象
实例没有prototype属性,他只有__proto__属性,这个属性指向他构造函数的prototype属性
构造函数的prototype属性是这个类的一个引用,在这里面可以看到这个类的所有东西
普通函数也有prototype属性,也是自身的一些属性
原型链继承的例子
function Elem(id) {
this.elem = document.getElementById(id)
}
Elem.prototype.html = (val) => {
if(val) {
this.elem.innerHTML = val
return this
}
else
return this.elem.innerHtml
}
Elem.prototype.on = (type, fn) => {
this.elem.addEventListener(type, fn)
return this
}
let dom = new Elem('div')
dom.html('hello world').on('click', () => {
alert(123)
})