Appearance
1.每一个函数(箭头函数除外), 都有一个自带的属性: prototype, 这个属性指向一个对象, 这个对象存储着给实例提供的公有的属性和方法,它有一个自带的属性: constructor, 这个属性指向当前函数, Function.prototype 除外, 它指向一个匿名函数,这个匿名函数没有 prototype 属性, 另外这个匿名函数有个 constructor 属性,自然是指向 Function,
2.每一个引用数据类型的值,有一个天生自带的属性: proto,这个属性指向父类的原型
js
{}.__proto__ === Object.prototype
[].__proto__ === Array.prototype
Array.prototype.__proto__ === Object.prototype
Object.prototype.__proto__ === null // 原型链尽头
// ...3.函数是引用数据类型的值, 所有每个函数(包括箭头函数)也都有一个天生自带的属性: proto, 这个属性指向父类的原型 -> Function.prototype
js
fn.__proto__ === Funtion.prototype
Array.__proto__ === Function.prototype
Object.__proto__ === Function.prototype
Function.__proto__ === Funtion.prototype
// ...
Function.prototype.__proto__ === Object.prototype4.函数的prototype是一个对象, 是引用数据类型值, 有一个天生自带的属性: proto, 这个属性指向父类的原型
js
fn.prototype.__proto__ === Object.prototype
Function.prototype.__proto__ === Object.prototype5.Object()构造函数的prototype指向一个对象,这个对象的__proto__指向null,这就是原型链的尽头
js
Object.prototype.__proto__ === null原型链
访问一个对象的属性时 先在自身属性中查找,找到返回 如果没有,再沿着__proto__这条隐式原型链上查找,找到返回 如果最终没找到,返回undefined
设置对象属性时,不会查找原型链,如果当前对象没有该属性,会直接添加该属性
为什么getElementById的上下文只能是document?
document的父类是Document,而只有Document.prototype中的getElementById这个方法
js
// example1
function Fn () {
this.x = 100
this.y = 200
this.getX = function () {
console.log(this.x)
}
}
Fn.prototype.getX = function () {
console.log(this.x)
}
Fn.prototype.getY = function () {
console.log(this.y)
}
let f1 = new Fn
let f2 = new Fn
console.log(f1.getX === f2.getX)
console.log(f1.getY === f2.getY)
console.log(f1.__proto__.getX === f2.__proto__.getX)
console.log(f1.__proto__.getX === f2.getX)
console.log(f1.getX === Fn.prototype.getX)
console.log(f1.constructor)
console.log(Fn.constructor.__proto__.constructor)
f1.getX()
f1.__proto__.getX()
f2.getY() // 函数前有 .,this 就是 . 之前的对象
Fn.prototype.getY()
// example2
function fun () {
this.a = 0
this.b = function () {
console.log(this.a)
}
}
fun.prototype = {
b: function () {
this.a = 20
console.log(this.a)
},
c: function () {
this.a = 30
console.log(this.a)
}
}
var f1 = new fun()
f1.b()
f1.c()
// example3
function C1 (name) {
if (name) {
this.name = name
}
}
function C2 (name) {
this.name = name
}
function C3 (name) {
this.name = name || 'Jack'
}
C1.prototype.name = 'Tom'
C2.prototype.name = 'Tom'
C3.prototype.name = 'Tom'
console.log((new C1().name) + (new C2().name) + (new C3().name))
// example3
function Fn (num) {
this.x = this.y = num
}
Fn.prototype = {
x: 20,
sum: function () {
console.log(this.x + this.y)
}
}
let f = new Fn(10)
console.log(f.sum === Fn.prototype.sum)
f.sum()
Fn.prototype.sum()
console.log(f.constructor)
// example4
function Fn () {
let a = 1
this.a = a
}
Fn.prototype.say = function () {
this.a = 2
}
Fn.prototype = new Fn
let f1 = new Fn
Fn.prototype.b = function () {
this.a = 3
}
console.log(f1.a)
console.log(f1.prototype)
console.log(f1.b)
console.log(f1.hasOwnProperty('b'))
// example3
// 编写两个方法plus/minus,实现如下功能
let n = 10
let m = n.plus(10).minus(5)
console.log(m)
~(function (proto) {
function check (x) {
return isNaN(x) ? 0 : Number(x)
}
function plus (x) {
x = check(x)
return this + x
}
function minus (x) {
x = check(x)
return this - x
}
proto.plus = plus
proto.minus = minus
})(Number.prototype)