Js中的原型链

8/12/2022 JS

# 什么是原型链

原型链,所有的原型构成了一个链条,这个链条我们称之为原型链(prototype chain)。

# 案例

因为obj中没有name属性自然打印的是undefined

    let obj = {

    }

    console.log(obj.name) // undefined
1
2
3
4
5

这个时候经历了什么呢?JS引擎线从Obj.address里寻找,发现没有找到,然后接着去找obj.__ proto __ 里面寻找,发现还是没找到,所以结果为undefined。我们可以给obj.__ proto __ 赋值

    let obj = {

    }

    obj.__proto__ = {
        name:'zhang'
    }

    console.log(obj.name) // zhang
1
2
3
4
5
6
7
8
9

或者这样

obj.__proto__ = {
    //这里一定要开辟一个空间,不能直接写obj.__proto__.__proto__ = {}
}
obj.__proto__.__proto__= {
    address:'上海'
}
console.log(obj.address); //上海
1
2
3
4
5
6
7

可以接着套

let obj = {
    name : 'harry',
    age:18
}

obj.__proto__ = {

}
obj.__proto__.__proto__= {
    
}
obj.__proto__.__proto__.__proto__= {
    address:'上海'
}
console.log(obj.address); //上海
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# js引擎会顺着这些原型不断的往上找,直到address这个属性。这些原型构成了原型链。

# 原型链的顶层

    let obj = {
        name : 'zhang'
    }
    console.log(obj.__proto__); // Object
    console.log(obj.__proto__.__proto__); //null
1
2
3
4
5

这里的Object就是顶层原型,如果再往上找,结果就是null了(已经到了末尾,这个链表指向为null)。

# 那么object是哪里来的呢

var obj1 = {}  //创建了一个对象

var obj2 = new Object() //创建了一个对象,针对object也有new这个过程
1
2
3

# new操作符的一个经历

  1. 现在内存中创建一个let obj2 = {}
  2. 再将this指向这个对象 this = obj2
  3. 再将函数的显示原型prototype赋值给前面的对象的隐式原型obj2.__ proto __ = Object.prototype
  4. 如果构造函数没有对象,则返回空值。反之返回创建出来的新对象(moni)。这里也就是return this。

# 验证一下

console.log(obj2.__proto__ === Object.prototype) //true
1

# 补充

原型链的类似链表结构,链表通过next链接,原型链通过__proto__链接

obj.__proto__  ---> Object.prototype ---> null
obj instanceof Object // true
Object.prototype.x = 'x'
console.log(obj.x) // 'x'

fun.__proto__ ---> Function.prototype ---> Object.prototype ---> null
fun instanceof Function // true
fun instanceof Object //true
Object.prototype.y = 'y'
console.log(fun.y) // 'y'

arr.__proto__  ---> Array.prototype ---> Object.prototype ---> null
arr instanceof Array // true
arr instanceof Object //true
Object.prototype.z = 'z'
console.log(arr.z) // 'z'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# instanceof 实现原理

// 跟遍历链表一样的方式
const instanceof = (A,B) => {
    let p = A
    while(A){
        if(p === B.prototype){
            return ture
        }
        p = p.__proto__
    }
    return false
}
1
2
3
4
5
6
7
8
9
10
11