我为什么要把 javascript.prototype
原型单独拿出一系列博客来写?
因为平时写js代码的时候很少用到!!!!
我为什么平时写js代码的时候很少用到?
因为平时我写js代码,特别是对象的时候.不出意外,99.99999%的情况都是使用字面量的写法!!!!
var obj = {
.....
}
一个简单的场景
我们使用字面量(99.9999%的情况都是如此)声明一个对象.
var obj = {
name: '李四',
age: 22
}
然后调用
obj.showInfo()
不出意外,肯定报错.且报错信息是 obj.showInfo is not function
..
到目前为止,从来都没有人怀疑过.
这里就应该报错.因为你没有定义这个方法.
那如果我调用obj.toString()方法呢?
[object Object]
我没有定义 toString
方法,为什么不报错,还正确执行了呢?
这个 toString
的方法是哪里来的?
Object.prototype
在解释 toString
方法哪里来的之前
有一个规则需要知道: (什么是规则?规则就是你可以先不去理解,但是必须强行记忆和知道的知识)
在js中函数也是对象,所有的函数对象上会有一个
.prototype
的属性.
Object 也是一个函数,所以,它也有 .prototype
属性.===> Object.prototype
打印一下 Object.prototype
这个对象上有哪些属性?
(请注意,在浏览器环境中打印,在Node.js环境中打印将会返回一个空对象)
所以,我们可以先暂时假定: 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)
现在在创建一个对象字面量,但内部没有 name
和 age
属性.
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 写时复刻==
网友评论