通天战队|「翻译」JavaScript的可视化学习之五:原型继承( 二 )


通天战队|「翻译」JavaScript的可视化学习之五:原型继承4、把可以共享的属性从构造函数中挪到原型上可以有效节省内存 。
每当我们试图访问实例上的属性时 , 引擎首先在本地搜索 , 以查看该属性是否在对象本身上定义 。 但是 , 如果它找不到我们要访问的属性 , 那么引擎会通过“__proto__”属性沿着原型链进行遍历!
通天战队|「翻译」JavaScript的可视化学习之五:原型继承5、查找属性时 , 通过__proto__属性沿着原型链进行遍历查找 。
这只是一次遍历 , 但它可以包含多层遍历!如果您继续往下看 , 您可能会注意到 , 当我展开“__proto__”对象时 , 没有包含一个属性“Dog.prototype” 。 “Dog.prototype”它本身是一个对象 , 这意味着它实际上是“Object”构造函数的一个实例!这意味着“Dog.prototype”还包含一个“__proto__”属性 , 它指向“Object.prototype”!
通天战队|「翻译」JavaScript的可视化学习之五:原型继承最后 , 我们知道了内置方法从何而来:它们在原型链上!
例如“.toString()”方法 。 它是在“dog1”对象上定义的吗?嗯不 。。。 它是在“dog1.__proto__”指向的“Dog.prototype”上定义的吗? 也不是!它是在对象“Dog.prototype.__proto__”指向的“Object.prototype”上定义的吗? 对!
通天战队|「翻译」JavaScript的可视化学习之五:原型继承6、原型链多层查找 。
我们刚刚使用了构造函数(`function Dog(){ 。。。 }`) , 当然它现在仍然是有效的JavaScript 。 不过 , ES6为构造函数和处理原型引入了一种更简单的语法:类!
类只是构造函数的语法糖 , 一切还是一样的!
我们用“class”关键字来编写类 。 类有一个“constructor”函数 , 它基本上就是我们用ES5语法编写的构造函数!我们要添加到原型中的属性是在类主体本身上定义的 。
通天战队|「翻译」JavaScript的可视化学习之五:原型继承7、ES6引进了构造函数的语法糖:类 。
类的另一个好处是 , 我们可以很容易地扩展其他类 。
假设我们要展示几只同一品种的狗 , 即吉娃娃!吉娃娃...当然还是狗狗 。 为了保持这个示例的简单性 , 我现在只将“name”属性传递给“Dog”类 , 而不是“name”、“breed”和“color” 。 但这些吉娃娃也能做一些特别的事 , 它们会小声叫唤 。 除了说“Woof!” , 吉娃娃也会说“Small Woof!” 。
在扩展类中 , 我们可以使用“super”关键字访问父类的构造函数 。 在本例中 , 我们必须把参数“name”传递给父类构造函数“super” 。
class Dog {constructor(name) {this.name = name}bark() {return 'Woof!'}}class Chihuahua extends Dog {constructor(name) {super(name)}smallBark() {return 'Small woof!'}}const myPet = new Chihuahua('Max')“myPet”能访问“Chihuahua.prototype”和“Dog.prototype”(并自动可以访问“Object.prototype” , 因为“Dog.prototype”是一个对象) 。
通天战队|「翻译」JavaScript的可视化学习之五:原型继承8、类和ES5的构造函数在原型继承上的表现是一致的 。


推荐阅读