理论+实践:从原型链到继承模式,掌握 Object 的精髓(二)(下)

简介: 理论+实践:从原型链到继承模式,掌握 Object 的精髓(二)(下)

对象关联


  • • 现在我们了解了 [[Prototype]] 机制就是存在于对象中的一个内部链接,他会引用到其他对象。
  • • 何为原型链?
  • • 如果在对象上没有找到需要的属性或方法引用,引擎就会先会在当前对象中查找,如果找不到,就在 [[Prototype]] 关联的对象进行查找。如果后者也没有找到需要的引用就会继续查找它的 [[Prototype]],直到 Object.prototype 为止。以此类推,这一系列的对象链接被称为 "原型链"。


创建关联


  • • 那 [[Prototype]] 机制的意义是什么?为什么要创建这些关联呢?
  • • 如下代码:
var foo = {
    something: function(){
        console.log('do something');
    }
};
var bar = Object.create(foo);
var.something(); // do something
  • • 使用 Object.create() 创建了一个新对象且关联到 foo,这样就可避免一些不必要的麻烦(比如使用 new 的构造函数调用会生成 .prototype 和 .constructor 引用)
  • • 注意:Object.create(null) 会创建一个空链接的对象,因为是空的,所有无法进行委托,并且由于这个对象没有原型链,在使用 instanceof 时也就无法进行判断,因此他们总是会返回 false。
  • • 在上述的代码中我们通过创建一个新的类来创建两个对象之间的关系,其实并不需要这么做,只需要通过委托关系来关联对象就足够了。
// Object.create()的 polyfill 代码
if(Object.create){
    Object.create = function(o){
        function F(){};
        F.prototype = o;
        return new F();
    }
}
  • • 上述代码使用一个一次性函数 F, 通过改写它的 .prototype 属性使其指向想要关联的对象,然后再使用 new F() 来构造一个新对象进行关联。
  • • Object.create() 的扩展:
var anotherObject = {
    a:2
};
var myObject = Object.create( anotherObject, {
    b: {
        enumerable: false,
        writable: true,
        configurable: false,
        value: 3
    },
    c: {
        enumerable: true,
        writable: false,
        configurable: false,
        value: 4
    }
});
myObject.hasOwnProperty( "a" ); // false
myObject.hasOwnProperty( "b" ); // true
myObject.hasOwnProperty( "c" ); // true
myObject.a; // 2
myObject.b; // 3
myObject.c; // 4
  • • Object.create() 的第二个参数指定了需要添加到新对象中的属性名以及这些属性的属性描述符。


小结


  1. 1. 当访问对象中不存在的一个属性时,[[Get]] 操作就会查找对象内部 [[Prototype]] 关联的对象,这个关联关系就是一条 "原型链"(有点像嵌套的作用域),在找到属性时会对它进行遍历。
  2. 2. 所有普通对象都有内置的 Object.prototype,指向原型链的顶端(比如说全局作用域), 如果在原型链中找不到指定的属性就会停止。
  3. 3. 关联两个对象最常用的方法就是用 new 关键字进行函数调用,在调用的第四个步骤中会创建一个关联到创建的新对象。
  4. 4. 使用 new 调用函数时会把新对象的 .prototype 属性关联到其他对象,带 new 的函数调用被称为构造函数调用
  5. 5. 对象之间是通过 [[Prototype]] 链关联的。
  6. 6. Object.create(null) 会创建一个空链接的对象,因为是空的,所有无法进行委托,并且由于这个对象没有原型链,在使用 instanceof 时也就无法进行判断,因此他们总是会返回 false。
  7. 7. 如果对象中的属性不直接存在于当前对象中而是存在于原型链上层时会出现三种情况:
  1. 1. 如果在 [[Prototype]] 原型链上层存在对象中的属性访问属性,并且没有被标记为只读(writable: false),那就会直接在当前对象中添加一个对象中的属性属性,则它是屏蔽属性。
  2. 2. 如果在 [[Prototype]] 原型链上存在对象中的属性属性,但是被标记为只读, 那就无法修改已有属性或在当前对象上创建屏蔽属性。如果在严格模式下运行,会直接抛出一个错误。否则,这条赋值语句就会被忽略。总之,不会发生屏蔽。
  3. 3. 如果在 [[Prototype]] 原型链上层存在对象中的属性并且它是一个 setter,那就一定会调用这个 setter。对象中的属性不会被添加到(可以说屏蔽到)当前对象中,也不会重新定义对象中的属性这个 setter
  1. 8. 使用 for...in 遍历对象和 in 操作符时都会查找对象的整条原型链。(无论属性是否可枚举)
  2. 9. 一个类其实就是一张蓝图,只是一个计划,并不是真正的可以交互的对象,我们必须通过实例化来调用所有公有数据属性,而这个实例化对象就是类的所有特性的一份副本
  3. 10. 多态:父类的一些通用行为可以被子类的行为重写。
  4. 11. 多态并不表示父类和子类有关联,子类得到只是父类的一个副本,类的继承就是复制。


特殊字符描述


问题标注 Q:(question)答案标注 R:(result)注意事项标准:A:(attention matters)详情描述标注:D:(detail info)总结标注:S:(summary)分析标注:Ana:(analysis)提示标注:T:(tips)

相关文章
|
7月前
|
前端开发 JavaScript
【面试题】原型与原型链 进一步理解~
【面试题】原型与原型链 进一步理解~
|
7月前
|
存储 C++
【C++】多态(重写)的实现过程及其原理【核心知识点精讲】(22)
【C++】多态(重写)的实现过程及其原理【核心知识点精讲】(22)
|
Java 程序员 编译器
继承的巧妙
继承的巧妙
34 0
|
29天前
ES6的类的实例化过程和传统面向对象语言有什么区别?
ES6 的类的实例化过程更加简洁、直观,并且与现代编程理念更加契合,减少了一些传统面向对象语言中可能存在的复杂性和冗余性。
|
7月前
|
Java 编译器 C#
【C++ 继承的多样性】C++ 多继承与虚拟继承:探究核心原理与应用实践
【C++ 继承的多样性】C++ 多继承与虚拟继承:探究核心原理与应用实践
199 1
|
7月前
|
Serverless PHP
当谈论面向对象编程时,这四个概念是非常重要的。以下是对接口、继承、封装和多态的简要说明
本文介绍了面向对象编程的四个核心概念:接口、继承、封装和多态。接口定义对象的行为规范,类通过实现接口确保符合所需行为。继承允许在已有类基础上创建新类,实现代码重用。封装是将数据和操作捆绑并隐藏内部细节,提高安全性和可维护性。多态使对象在运行时能表现出不同行为,增加代码灵活性和可扩展性。文中还提供了代码示例来说明这些概念。
53 0
|
7月前
|
设计模式 算法
|
7月前
|
Java
Java面向对象编程,解释封装、继承和多态的概念。
Java面向对象编程,解释封装、继承和多态的概念。
82 2
|
存储 JavaScript 前端开发
理论+实践:从原型链到继承模式,掌握 Object 的精髓(二)(上)
理论+实践:从原型链到继承模式,掌握 Object 的精髓(二)
理论+实践:从原型链到继承模式,掌握 Object 的精髓(二)(下)
理论+实践:从原型链到继承模式,掌握 Object 的精髓(二)(下)