js中原型链相关

86 阅读2分钟

这块需要大家先自行了解一下什么原型对象,为什么需要原型对象,怎么访问,这里就不展开说了

1. 先抛出一个场景

function Fn(){
}
let f = new Fn()
console.log(f.toString())
//则会返回[object object]

上面,我并没有定义 这个 toString() 方法为什么还是生效?

答案:是因为这个方法存在 Object 对象中的原型中,f 通过原型链找到了这个方法

2. 首先介绍一下什么是原型链

每一个对象都有原型,原型本身又是对象,所以原型又有原型,以此类推形成一个链式结构,称为原型链(原型链的终点是null)

先浅浅抛出一张图

3. 原型链的访问规则

当访问一个对象的成员变量时,会首先访问它自身的成员变量,如果有则访问。没有则在原型中寻找,能找到就访问,不能找到则继续往原型的原型中寻找,以此类推,如果找到原型链的顶端还是找不到,则程序报错:xxx is not a function

说明一下报错的原因,执行p1.learn(),p1找不到learn方法会报undefined的错误,然后加上小括号调用函数,所以会报不是function的错误

4. 注意点

原型对象 : 常用来存储具有共同特征的数据(多个不同的实例对象可以调用)

        Person.prototype.type = '哺乳动物'
        Person.prototype.country = '中国'
        Person.prototype.eat = function(){
            console.log(this.name + '吃东西')
        }

p1.toString,p1自己没有toString, p1的原型也没有toString, 但是为什么不报错呢?

原因: p1的原型的原型有toString

        //查看p1的原型
        console.log( p1.__proto__.constructor )//Person
        console.log( Person.prototype === p1.__proto__ )//true
 
        //查看p1的原型的原型
        console.log( p1.__proto__.__proto__.constructor )//Object
        console.log( Object.prototype === p1.__proto__.__proto__ )//true
 
        //查看p1的原型的原型的原型
        console.log( p1.__proto__.__proto__.__proto__ )//null

注意点:

  • 所有的对象的原型都最终指向内置构造函数Object的原型对象,再最终指向null
  • 构造函数本身也是一个对象,也是由构造函数创建的,也有自己的原型链(作用不大,仅作了解)
  • 只要是对象就有原型,原型对象是由内置构造函数Object创建的

5. 思考

为什么 arr.toString() 方法和对象的 toString() 方法得到的结果不同

回答:数组的原型含有 toString 方法用来转换成字符串,对象的 toString 方法是 Object 的原型里面的方法,是专门用来监测数据类型的

let arr=[1,2,3,4]
console.log(arr.toString())
//则会返回1,2,3,4 
function Fn(){
}
let f = new Fn()
console.log(f.toString())
//则会返回[object object]