美文网首页
JavaScript.prototype 和 继承 - 01

JavaScript.prototype 和 继承 - 01

作者: 人话博客 | 来源:发表于2019-02-27 19:57 被阅读0次

我为什么要把 javascript.prototype 原型单独拿出一系列博客来写?

因为平时写js代码的时候很少用到!!!!

我为什么平时写js代码的时候很少用到?

因为平时我写js代码,特别是对象的时候.不出意外,99.99999%的情况都是使用字面量的写法!!!!

var obj = {
    .....
}

一个简单的场景

我们使用字面量(99.9999%的情况都是如此)声明一个对象.

var obj = {
    name: '李四',
    age: 22
}

然后调用

obj.showInfo()

不出意外,肯定报错.且报错信息是 obj.showInfo is not function..

image.png

到目前为止,从来都没有人怀疑过.

这里就应该报错.因为你没有定义这个方法.

那如果我调用obj.toString()方法呢?

[object Object]

我没有定义 toString 方法,为什么不报错,还正确执行了呢?

这个 toString 的方法是哪里来的?


Object.prototype

在解释 toString 方法哪里来的之前

有一个规则需要知道: (什么是规则?规则就是你可以先不去理解,但是必须强行记忆和知道的知识)

在js中函数也是对象,所有的函数对象上会有一个 .prototype 的属性.

Object 也是一个函数,所以,它也有 .prototype 属性.===> Object.prototype

打印一下 Object.prototype 这个对象上有哪些属性?
(请注意,在浏览器环境中打印,在Node.js环境中打印将会返回一个空对象)

image.png

所以,我们可以先暂时假定: obj.toString 方法是来自 Object.prototype 对象上的.

代码改造

之前我们的代码是

var obj = {
    name: '李四',
    age: 22
}

console.log(obj.toString())

[object Object]

之前也说过,一般在书写js代码创建一个对象时.

不夸张的说 99.9999999% 的情况都是写的对象字面量(就像上述那样)

但实际上,这段代码也可以改写成这样.

var obj = new Object()
obj.name = '李四'
obj.age = 22

我们可以理解成,对象字面量其实是一个语法糖.
它帮我们隐式的调用了 new Object().

所以,在我们写js代码利用对象字面量创建对象的时候,new Object() 其实无处不在(因为99.9999%的情况下,我们都是使用对象字面量来创建对象.反而忽略了new的存在.).


new Object()

现在我们知道了,使用对象字面量创建对象只是一个语法糖.
其内部帮我们调用了 new Object().

如果要了解为什么 obj.toString() 没问题.

还需要知道一个前置规则(第一个是:所有的函数都包含一个.prototype属性)

所有构造的对象(隐式或显式(用new).都会从它的构造函数对象的prototype对象继承.

于是,可以画一下面这张图.

image.png
  • Object 是一个函数,它有一个属性叫 .prototype.
  • .prototype 属性本身也是一个对象,它也右边那些属性和方法.
  • obj 实际上是 Object 函数构造出出来的实例.所以,根据第二条规则,通过 new Object() 创建出来的对象,都会从 Object.prototype 对象上继承属性和方法.
  • 所以,我们调用 obj.toString 实际上是调用的 Object.protoype.toString 方法.

证明obj.toString === Object.prototype.toString

我们先尝试修改一下 Object.prototype.toString 让它专门为 obj 对象来使用.

Object.prototype.toString = function () {
  console.log(this.name, this.age)
}

obj.toString()
李四 22

关于 prototype 对象属性的COW(copy on write)

现在在创建一个对象字面量,但内部没有 nameage 属性.

const obj2 = {}

根据上述的规则一 & 规则二.所以下列这条等式是成立的.

console.log(obj2.toString === Object.prototype.toString) // true.

如果我现利用 obj2 修改了 toString 函数,会对 obj 产生影响吗?

obj2.toString = function() {
    console.log('toString函数被我重写了.')
}
obj.toString()

结果

李四 22

除非修改 prototype 对象本身,否则继承自这个 prototype 对象的对象,做的任何修改只会影响此对象自己.
而不会影响到其他的对象.
这个就叫做原型对象的 COW ==copy on write 写时复刻==

相关文章

网友评论

      本文标题:JavaScript.prototype 和 继承 - 01

      本文链接:https://www.haomeiwen.com/subject/tdkquqtx.html