烟台网站建设力推企汇互联见效付款,一个优秀的个人网站,七台河新闻头条,企业在网站建设后期需要做什么一、JavaScript原型链
在真正实现继承之前#xff0c;我们先来理解一个非常重要的概念#xff1a;原型链。
我们知道#xff0c;从一个对象上获取属性#xff0c;如果在当前对象中没有获取到就会去它的原型#xff08;__proto__#xff09;上面获取#xff1a;
二、…一、JavaScript原型链
在真正实现继承之前我们先来理解一个非常重要的概念原型链。
我们知道从一个对象上获取属性如果在当前对象中没有获取到就会去它的原型__proto__上面获取
二、Object的原型
那么什么地方是原型链的尽头呢比如第三个对象是否也是有原型__proto__属性呢 我们会发现它打印的是 [Object: null prototype] {}
事实上这个原型就是我们最顶层的原型了从Object直接创建出来的对象的原型都是 [Object: null prototype] {}。 那么我们可能会问题 [Object: null prototype] {} 原型有什么特殊吗 特殊一该对象有原型属性__proto__但是它的原型属性已经指向的是null也就是已经是顶层原型了 特殊二该对象上有很多默认的属性和方法 创建Object对象的内存图: 原型链关系的内存图:
三、Object是所有类的父类
从我们上面的Object原型我们可以得出一个结论原型链最顶层的原型对象就是Object的原型对象
四、通过原型链实现继承
如果我们现在需要实现继承那么就可以利用原型链来实现了
目前stu的原型是p对象而p对象的原型是Person默认的原型里面包含running等函数注意步骤4和步骤5不可以调整顺序否则会有问题执行stu.studying()时报错。 五、原型链继承的弊端
但是目前有一个很大的弊端某些属性其实是保存在p对象上的 第一我们通过直接打印对象是看不到这个属性的 第二这个属性会被多个对象共享如果这个对象是一个引用类型那么就会造成问题 第三不能给Person传递参数因为这个对象是一次性创建的没办法定制化
六、借用构造函数继承
为了解决原型链继承中存在的问题开发人员提供了一种新的技术: constructor stealing(有很多名称: 借用构造函数或者称之为经典继承或者称之为伪造对象)
steal是偷窃、剽窃的意思但是这里可以翻译成借用
借用继承的做法非常简单在子类型构造函数的内部调用父类型构造函数.
因为函数可以在任意的时刻被调用因此通过apply()和call()方法也可以在新创建的对象上执行构造函数 强调: 借用构造函数也是有弊端:
第一个弊端: Person函数至少被调用了两次第二个弊端: stu的原型对象上会多出一些属性, 但是这些属性是没有存在的必要
以上这种方式称为组合继承是JavaScript最常用的继承模式之一
如果你理解到这里, 点到为止, 那么组合来实现继承只能说问题不大但是它依然不是很完美但是基本已经没有问题了(不成问题的问题, 基本一词基本可用, 但基本不用)
组合继承存在什么问题呢?
组合继承最大的问题就是无论在什么情况下都会调用两次父类构造函数。 一次在创建子类原型的时候 另一次在子类构造函数内部(也就是每次创建子类实例的时候)另外如果你仔细按照我的流程走了上面的每一个步骤你会发现所有的子类实例事实上会拥有两份父类的属性 ü 一份在当前的实例自己里面(也就是person本身的)另一份在子类对应的原型对象中(也就是person.__proto__里面) 当然这两份属性我们无需担心访问出现问题因为默认一定是访问实例本身这一部分的