javascript的原型和原型链深入理解

在聊原型之前先聊一聊如何拷贝结构的方法,我们知道深拷贝对象的方法可以用递归和JSON,那如果只拷贝结构呢?

可以用工厂模式,也可以称为工厂函数,简单理解,就是将一些原材料放到函数中加工出全部一样的产品。工厂函数写法类似于构造函数,如下:

function createUser(name, age) {
    return {
        name, age, getName() {
            return this.name
        }
    }
 }
let user1 = createUser('Peter', 28)
let user2 = createUser('Andy', 18)
user1.name  // Peter

工厂函数的缺点就是:user1 和 use2 虽然用的是同一个函数,但是是独立存在的,这样创建会很浪费空间

console.log(user1.getName == user2.getName)  // false

所以我们就可以用到原型,原型就是让对象之间有共享的部分,不管创建多少个user都是引用的同一个地址,大大节约了存储空间

function createUser(name, age) {
    this.name = name
    this.age = age
}
createUser.prototype.getName = function () {
    console.log(this.name)
}
let user1 = new createUser('Peter', 28)
let user2 = new createUser('Andy', 18)
user1.name  // Peter
console.log(user1.getName == user2.getName)  // true

原型

构造函数的prototype属性

  • 每个函数都有一个 prototype 属性, 它默认指向一个Object空对象(即称为: 原型对象)

  • 原型对象中有一个属性 constructor, 它指向函数对象

prototype的作用

  • 用于将一些方法或者属性添加在 prototype 属性上,每次 new 创建的实例对象都可以共享到 prototype 上的方法和属性

实例对象的__proto__属性

  • 每个实例对象都有一个 __proto__ 属性,它指向函数中的 prototype 属性(即称为:对象原型)

显示原型和隐式原型

函数 => 构造函数 显示原型 prototype

对象 => 实例对象 隐式原型 __proto__

构造函数中的 prototype 相等于 实例对象中的 __proto__


原型链

每创建一次函数,解析器就会按照特定的规则给函数添加一个 prototype 属性指向原型对象。原型对象会默认获得一个 constructor 属性,指回与之关联的构造函数。

显示原型和隐式原型指向同一个空对象,这个空对象也是一个实例对象,由Object实例出来的,该空对象的隐式原型指向Object的显示原型,但是Object比较特殊,他的隐式原型是null

但是 Object 是由 function 实例出来的,所以 Object的隐式原型指向函数的显示原型,函数的显示原型的隐式原型又指向对象的显示原型

构造函数也是由Function实例出来的,所以构造函数的隐式原型指向function的显示原型

整个原型链的结构如下:

原型链查找规则

在通过对象访问属性时,会按照这个属性的名称开始搜索,它会遵循以下的查找顺序:

1. 搜索开始于实例对象本身,如果在这个实例上发现了属性名,则返回该名称对应的值,不再继续搜索

2. 如果没有找到这个属性,则会沿着实例对象的 __proto__ 去原型对象中查找,如果在原型对象中找到了这个属性,再返回对应的值,不再继续搜索

3.如果还没有找到,继续沿着原型对象的__proto__中去找,Object的原型对象的__proto__是null,如果在Object对象的原型中都没有找到,就到头了,直接返回undefined

总结

原型

  • 就是用来使对象中需要共享的部分共享,节约存储空间

  • 每创建好一个构造函数,解析器就会自动添加一个prototype属性执行一个空对象(原型对象),原型对象也会添加一个constructor属性指回该构造函数

  • 用new创建出来的对象称为实例对象,在创建的时候也会自动添加一个__proto__属性指向空对象 构造函数的.prototype == 实例对象的.__proto__

原型链

  • 原型链查找规则:先在自身上找,没有就沿着 __proto__ 去原型对象中查找,都找不到就返回 undefined

猜你喜欢

转载自blog.csdn.net/m0_63689815/article/details/128981030