浅聊一下

JavaScript 中的原型是理解该言语核心特性的要害之一。在面试中,掌握原型概念通常是一个重要的议题。今天咱们将深入探讨 JavaScript 中的原型,而且文章结束附带一道你绝对想不到的网易面试题…

什么是原型?

咱们先来聊聊究竟什么是原型

原型(prototype)是函数天生就具有的特点,它界说了结构 函数制造出的目标的公共祖先。 经过该结构函数产生的目标,能够隐式承继到原型上的特点和办法

你说这究竟是啥呀?语文欠好,看不懂…那咱们直接上代码

function Person() {
    this.name = '张三';
    this.age = 18;
}
let p = new Person();
console.log(p);

在js中,咱们用这种办法界说一个类,然后new一下发明一个目标,代码较为简略,来看打印结果

请必须搞懂原型(附你想不到的网易面试题)
咱们能够看到,所创立的目标p承继到了Person( )中的特点,而且能够打印出来看到,那么咱们再来上一段代码

Person.prototype.say = function () {
    return '我是张三'
}
console.log(p.say());
console.log(p);

这次咱们调用p.say()

请必须搞懂原型(附你想不到的网易面试题)
在这儿咱们能够看到p.say()的确被调用了,阐明p身上的确有这个办法,但是打印p的时分却没有显现出来,所以乎,咱们能够称function Person()是p的显现原型,而Person.prototype是p的隐式原型

为什么需要原型?

因为能够提取公有特点,简化代码执行

你说这话说的这么粗陋,我仍是看不懂…话又不多说,直接上代码

Car.prototype.name = 'BMW';
Car.prototype.lang = 4900; 
Car.prototype.height = 1400;
function Car(owner,color){
    this.owner = owner;
    this.color = color;
}
var car = new Car('L','black');
var car2 = new Car('Y','pink');

这儿有一个“别摸我”牌轿车的结构函数,Car结构函数的原型上咱们界说了公共特点,而函数里有有颜色和具有者,这些是需要“私家定制”的,所以在new一个目标的时分,相同的特点就不会再重复创立,直接拜访隐式原型就能够拜访到。在这儿“L”和“Y”别离购买了一辆“别摸我”,而且别离定制了颜色…

细节

  • 实例目标是无法修正原型的特点和办法的
Car.prototype.name = 'BMW';
Car.prototype.lang = 4900;
Car.prototype.height = 1400;
function Car(owner,color){
    this.owner = owner;
    this.color = color;
}
var car = new Car('L','black');
var car2 = new Car('Y','pink');
car.name = '劳斯莱斯'
console.log(car);
console.log(car2.name);

聪明的掘友来看看这儿输出什么?

请必须搞懂原型(附你想不到的网易面试题)

咱们本意上是想修正他们公共特点上的name,我让car.name=“劳斯莱斯”,但是将他们打印出来今后,咱们发现car2的姓名任然没有改动,就像“别摸我”公司卖给我一辆轿车,我叫其间的一辆为大黄,但是你并不能改动他的品牌姓名叫“别摸我”吧…

那么咱们怎么修正他们公共的姓名呢?让公司改名呗!

Car.prototype.name = '大黄';
console.log(car);
console.log(car2.name);

太狠了,把公司名都改了…现在叫大黄

请必须搞懂原型(附你想不到的网易面试题)

  • 实例目标是无法删去原型的特点和办法的

已然个人是无法改动品牌的姓名的,那么我个人要把你品牌的姓名删了,那你能忍?

Car.prototype.name = 'BMW';
Car.prototype.lang = 4900;
Car.prototype.height = 1400;
function Car(owner,color){
    this.owner = owner;
    this.color = color;
}
var car = new Car('L','black');
var car2 = new Car('Y','pink');
car.name = '劳斯莱斯'
Car.prototype.name = '大黄';
delete car.name
console.log(car);
console.log(car2.name);

不必猜,你只能掠夺你自己车的姓名,而car和car2的品牌名仍旧叫大黄

请必须搞懂原型(附你想不到的网易面试题)

要删去品牌名,相同得让公司自己改呀!

Car.prototype.name = 'BMW';
Car.prototype.lang = 4900;
Car.prototype.height = 1400;
function Car(owner,color){
    this.owner = owner;
    this.color = color;
}
var car = new Car('L','black');
var car2 = new Car('Y','pink');
car.name = '劳斯莱斯'
Car.prototype.name = '大黄';
// delete car.name
delete Car.prototype.name
console.log(car.name);
console.log(car2.name);

因为你自己叫自己的车为劳斯莱斯,所以car的姓名仍是有的

请必须搞懂原型(附你想不到的网易面试题)

原型链

原型链是什么呢?

顺着目标的隐式原型不断向上查找上一级的隐式原型,直到找到目标或许一直到null, 这种查找联系称为原型链

举一个例子,你把他人的“别摸我”撞坏了,他找你(你的显现原型)赔钱,你拿不出,找你老婆(你的隐式原型),他就找到你爸爸(你爸爸的显现原型),你爸爸拿不出就找到你妈妈(你爸爸的隐式原型),你妈妈也拿不出,所以找你爷爷(爷爷的显现原型),又找不到,还找你奶奶(爷爷的隐式原型),再往上没人了,所以只能认栽…

原型链也是这样,小二,上个代码

<script>
    Ground.prototype.lastName = "wang";
    function Ground(){
    }
    var ground = new Ground();
    Father.prototype = ground;
    function Father(){
        this.name = "zhangsan";
    }
    var father = new Father();
    Son.prototype = father;
    function Son(){
        this.hobbit = "play";
    }
    var son = new Son();
    console.log(son.lastName+son.name);
</script>

让咱们逐渐剖析:

  1. 首先,界说了一个名为 Ground 的结构函数,然后给 Ground.prototype 目标添加了一个 lastName 特点,其值为 “wang”。
  2. 接着,界说了一个 Father 结构函数,其间经过 this.namename 特点设置为 “zhangsan”。
  3. 然后,创立了一个 ground 目标实例,它的原型是 Ground.prototype。因为 Ground.prototype 上有 lastName 特点,所以 ground 实例也能拜访到 lastName 特点。
  4. 接下来,将 Father.prototype 设置为 ground 目标,这样 Father 结构函数的实例将会承继 ground 目标的特点和办法。
  5. 界说了一个 Son 结构函数,其间经过 this.hobbithobbit 特点设置为 “play”。
  6. 最后,创立了一个 son 目标实例,它的原型是 Father.prototype,因而它承继了 Father 结构函数中的 name 特点,同时也能经过原型链拜访 lastName 特点。因而,console.log(son.lastName + son.name) 会输出 “wangzhangsan”。

你想不到的网易面试题

一切的目标最终都会承继自 Object.prototype?

乍一看,好像没什么不对劲,可这个“一切”两个字又让人望而生畏,那么答案究竟是什么呢? 错!大错特错

为什么?,因为咱们还有一种创立目标的办法Object.create()

<script>
    //Object.create(obj)
    let obj = {
        a:1
    }
    let obj2 = Object.create(obj)
</script>

来看看打印obj2的结果

请必须搞懂原型(附你想不到的网易面试题)

在这儿咱们能够看到obj2承继了obj,那么咱们再来看

let obj3 = Object.create(null)

再来打印obj3

请必须搞懂原型(附你想不到的网易面试题)
咱们能够看到并没有报错,obj3里面什么也没有,并没有承继到Object

这是为什么呢?这儿涉及到一个美丽的错误,咱们的null用typeof判断出来的类型但是Object啊 至于为什么,大家能够去我曾经的文章看看(“探秘JavaScript:类型判断的奇妙世界(一)” – (juejin.cn))

请必须搞懂原型(附你想不到的网易面试题)

结束

原型看完这篇基本上就搞定了,舒舒服服上床睡觉等待春节,嘿嘿嘿……