原型链
原型五大规则
- 所有的引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性。
// object
var obj = {}
obj.a = 100 // 100
// array
var arr = []
arr.a = 100 // 100
// function
function fn() {}
fn.a = 100 // 100
- 所有的引用类型(数组、对象、函数),都有一个
__proto__
属性,属性值是一个普通的对象。
// object
var obj = {}
console.log(obj.__proto__) // { constructor: ƒ, __defineGette...
// array
var arr = []
cosnole.log(arr.__proto__) // { constructor: ƒ, __defineGette...
// function
function fn() {}
console.log(fn.__proto__) // { constructor: ƒ, __defineGette...
- 所有的函数(函数),都有一个prototype(显式原型)属性,属性值也是一个普通的对象
// object
var a = {}
cosnole.log(a.prototype) // undefined
// function
function fn() {}
console.log(fn.prototype) // { constructor: ƒ }
- 所有的引用类型(数组、对象、函数),proto属性值指向它的构造函数的
prototype
属性值
var obj = {}
console.log(obj.__proto__ === Object.prototype) // true
// Object 是内置构造函数
- 当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的proto(即它的构造函数的prototype)中寻找。
// 构造函数(规范命名,首字母大写)
function Foo(name, age) {
this.name = name
this.age = age
...
// return this // 默认返回
}
Foo.prototype.alertName = function() {
console.log(this.name, 'prototype')
}
// 创建实例
var f = new Foo('zhangsan', 12)
f.printName = function() {
console.log(this.name, '__proto__')
}
f.printName() // 'zhangsan', '__proto__' f自身有这个属性
f.alertName() // 'zhangsan', 'prototype' f没有这个属性,它的构造函数Foo的prototype有
f.consoleName() // undefined f、Foo都没有
f.name.toUpperCase() // 'ZHANGSAN' f.__proto__.__proto__
原型链继承
先讨论new一个对象的过程
function Foo(name, age) {
this.name = name
this.age = age
// return this 默认有这一行
}
var f = new Foo('zhangsan', 12)
// 四个过程
// 1.创建一个空对象
var obj = new Object()
// 2.让Foo中的this指向obj, 并执行Foo的函数体
var result = Foo.call(obj)
// 3.设置原型链,将obj的__proto__成员指向了Foo函数对象的prototype成员对象
obj.__proto__ = Foo.prototype
// 4.判断Foo的返回值类型,如果是值类型,返回obj;如果是引用类型,返回这个引用类型的对象。
if (typeof result === 'object') {
f = result
} else {
f = obj
}
实现一个原型继承的实例
// 构造函数
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 {
retrun elem.innerHTML
}
}
Elem.prototype.on = function (type, fn) {
var elem = this.elem
elem.addEventListener(type, fn)
}
// <div id="div1">123</div>
var div1 = new Elem('div1')
// html
console.log(div1.html()) // 123
div1.html('aaa') // <div id="div1">aaa</div>
// on
div1.on('click', function(){
console.log('this is click')
})
网友评论