故事背景


Ref: 你不知道的javascript之Object.create 和new区别

var Base = function () {}
(1) var o1 = new Base();
(2) var o2 = Object.create(Base);  // <----推荐
  • (1) 使用的是__proto__
// var o1 = new Object();
o1.__proto__ = Base.prototype;
Base.call(o1);
  • (2) 使用的是prototype
Object.create =  function (o) {
var F = function () {};
F.prototype = o;
return new F();
};

Object.create 失去了原来对象的属性的访问。

添加 Base.prototype.a = 3 后,依旧如此。

如此一来,得到的效果就是:

"通过Object.create构造的话,是连Base原型上的属性都访问不到的。"

因为他压根就没有指向他的prototype!

__proto__ 和 prototype 的区别


Ref: js中__proto__和prototype的区别和关系?

 

* 显式原型 explicit prototype property:

每一个函数在创建之后都会拥有一个名为prototype的属性,这个属性指向函数的原型对象。
Note:通过Function.prototype.bind方法构造出来的函数是个例外,它没有prototype属性。
 
作用:用来实现基于原型的继承与属性的共享
 

* 隐式原型 implicit prototype link:

JavaScript中任意对象都有一个内置属性[[prototype]],大多数浏览器都支持通过__proto__来访问。
 - ES5前,大多数浏览器都支持通过__proto__来访问。
 - ES5中,有了对于这个内置属性标准的Get方法Object.getPrototypeOf()。
Note: Object.prototype 这个对象是个例外,它的__proto__值为null。
 
作用:构成原型链,同样用于实现基于原型的继承
举个例子,当我们访问obj这个对象中的x属性时,如果在obj中找不到,那么就会沿着__proto__依次查找。
 

* 二者的关系:

隐式原型指向创建这个对象的函数(constructor)的prototype

 
构造函数(对象) --> prototype
|
|---- 创建了这个对象 --> __proto__
 
 
 

1. 对象字面量的方式

这个对象是通过对象字面量构造出来的。

var person1 = {
name: 'cyl',
sex: 'male'
};

形如这个形式的叫做对象字面量。构造出的对象,其[[prototype]]指向Object.prototype。

2. new 的方式

这个对象是由构造函数构造出来的。

function Person(){}
var person1 = new Person();

通过new操作符调用的函数就是构造函数。由构造函数构造的对象,其[[prototype]]指向其构造函数的prototype属性指向的对象。

每个函数都有一个prototype属性,其所指向的对象带有constructor属性,这一属性指向函数自身。(在本例中,person1的[[prototype]]指向Person.prototype)

3. ES5中的Object.create()

这个对象是由函数Object.create构造的。

var person1 = {
name: 'cyl',
sex: 'male'
}; var person2 = Object.create(person1);

解析:

function object(o){
function F(){}
F.prototype = o;
return new F()
}

如下可见:person2.__proto__ === person1 ==== person1.prototype

//以下是用于验证的伪代码
var f = new F();
//于是有
f.__proto__ === F.prototype //true
//又因为
F.prototype === o;//true
//所以
f.__proto__ === o;

正视历史


Why we need Prototype 模式?

Ref: Javascript继承机制的设计思想

Ref: Javascript 面向对象编程(一):封装

Brendan Eich想到C++和Java使用new命令时,都会调用"类"的 构造函数(constructor)。

他就做了一个简化的设计,在Javascript语言中,new命令后面跟的不是类,而是构造函数。

起因:prototype属性的引入 - 为了解决属性共享问题

为构造函数设置一个prototype属性,包含一个对象(以下简称"prototype对象"),所有实例对象需要共享的属性和方法,都放在这个对象里面;

那些不需要共享的属性和方法,就放在构造函数里面。

构造函数de验证方法:

alert(cat1.constructor == Cat); //true
alert(cat2.constructor == Cat); //true

alert(cat1 instanceof Cat); //true
alert(cat2 instanceof Cat); //true

Prototype模式de验证方法:

alert(Cat.prototype.isPrototypeOf(cat1)); //true
alert(Cat.prototype.isPrototypeOf(cat2)); //true

// 某一个属性到底是本地属性(非共享),还是继承自prototype对象的属性(共享)
alert(cat1.hasOwnProperty("name")); // true
alert(cat1.hasOwnProperty("type")); // false // 无所谓本地属性or共享属性
alert("name" in cat1); // true
alert("type" in cat1); // true

Why we need __proto__ 模式?

Ref: js中__proto__和prototype的区别和关系?

对象具有属性__proto__,可称为隐式原型;

一个对象的隐式原型指向:构造该对象的构造函数的原型【向上的指针】,这也保证了实例能够访问在构造函数原型中定义的属性和方法。

方法这个特殊的对象,除了和其他对象一样有上述_proto_属性之外,还有自己特有的属性——原型属性(prototype),这个属性是一个指针,指向一个对象,这个对象的用途就是包含所有实例共享的属性和方法(我们把这个对象叫做原型对象)。

原型对象也有一个属性,叫做constructor,这个属性包含了一个指针,指回原构造函数。

 
Object.prototype 的__proto__属性指向null
 
原型对象的__proto__ -- 指向 --> Object.prototype
 
 
构造函数(对象) --> prototype -- 指向 --> 原型对象(constructor属性 有一个指针 指回构造函数)
|----------------------- __proto__ ------------> 函数的构造函数是Function,所以,__proto__指向了Function.prototype
|
|---- 创建了这个对象 --> __proto__  -- 指向 --> 原型对象
 
 

(完)

 

[JS] Topic - Object.create vs new的更多相关文章

  1. js创建对象 object.create()用法

    Object.create()方法是ECMAScript 5中新增的方法,这个方法用于创建一个新对象.被创建的对象继承另一个对象的原型,在创建新对象时可以指定一些属性. 语法: Object.crea ...

  2. [JS] Topic - why "strict mode" here

    Ref: Javascript 严格模式详解 使得Javascript在更严格的条件下运行: - 消除Javascript语法的一些不合理.不严谨之处,减少一些怪异行为; - 消除代码运行的一些不安全 ...

  3. 【前端】js中new和Object.create()的区别

    js中new和Object.create()的区别 var Parent = function (id) { this.id = id this.classname = 'Parent' } Pare ...

  4. js Object.create 初探

    1.作用 Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__. https://developer.mozilla.org/zh-CN/docs/W ...

  5. js中的new操作符与Object.create()的作用与区别

    js中的new操作符与Object.create()的作用与区别 https://blog.csdn.net/mht1829/article/details/76785231 2017年08月06日 ...

  6. js继承之Object.create()

    通过 Object.create() 方法,使用一个指定的原型对象和一个额外的属性对象创建一个新对象.这是一个用于对象创建.继承和重用的强大的新接口.说直白点,就是一个新的对象可以继承一个对象的属性, ...

  7. js学习日记-new Object和Object.create到底干了啥

    function Car () { this.color = "red"; } Car.prototype.sayHi=function(){ console.log('你好') ...

  8. JS - Object.create(prototype)方法

    用Object.create(prototype)方法创建一个对象,这个对象的原型将指向这个传入的prototype参数

  9. 使用 Object.create实现js 继承

    二.Object.create实现继承 本文将来学习第七种继承方式Object.create()方法来实现继承,关于此方法的详细描述,请戳这里.下面来通过几个实例来学习该方法的使用: var Pare ...

随机推荐

  1. 什么是SASS

    一.什么是SASS SASS是一种CSS的开发工具,提供了许多便利的写法,大大节省了设计者的时间,使得CSS的开发,变得简单和可维护. 本文总结了SASS的主要用法.我的目标是,有了这篇文章,日常的一 ...

  2. android:制作 Nine-Patch 图片

    它是一种被特殊处理过的 png 图片,能够指定哪些区域可以被拉伸而 哪些区域不可以. 那么 Nine-Patch 图片到底有什么实际作用呢?我们还是通过一个例子来看一下吧.比如 说项目中有一张气泡样式 ...

  3. python unknown error: DevToolsActivePort file doesn't exist 问题解决

    解决方案: from selenium.webdriver.chrome.options import Options chrome_options = Options() chrome_option ...

  4. 用户人品预测大赛--getmax队--竞赛分享

     用户人品预测大赛--getmax队--竞赛分享  DataCastle运营 发表于 2016-3-24 14:49:32      533  0  0 答辩PPT  

  5. 【转】苹果App Store审核指南中文翻译(更新)

    (注:<苹果应用商店审核指南>中文翻译最近一次更新为2013-03-04,文中红色部分是相对于2013-03-04版本的新增内容,绿色部分代表更改的内容,蓝色表示苹果相关官方文档的链接.) ...

  6. 卸载系统自动jdk

    执行下面的代码可以看到当前各种JDK版本和配置: sudo update-alternatives --config java   卸载系统自动jdk [root@localhost soft]# r ...

  7. 如何免费的让网站启用https

    本文源自酷壳:如何免费的让网站启用HTTPS 今天,我把CoolShell变成https的安全访问了.我承认这件事有点晚了,因为之前的HTTP的问题也有网友告诉我,被国内的电信运营商在访问我的网站时加 ...

  8. 怎么去掉Xcodeproject中的某种类型的警告 Implicit conversion loses integer precision: &#39;NSInteger&#39; (aka &#39;long&#39;) to &#39;int32

    问题描写叙述  在我们的项目中,通常使用了大量的第三方代码,这些代码可能非常复杂,我们不敢修改他们,但是作者已经停止更新了,当sdk升级或者是编译器升级后,这些遗留的代码可能会出现许很多多的警告,那么 ...

  9. 第三部分:Android 应用程序接口指南---第二节:UI---第八章 Toast通知

    第8章 Toast通知 Toast通知是在窗口前面弹出的信息.它只占有信息所需要的空间量,并且用户当前的activity仍然是可见的.可互动的.这种通知自动地淡入和淡出,它不接受交互事件.他相当于一种 ...

  10. 关于烦躁的网页编码问题utf-8,gb2312。终于自己实践了一遍

    俗话说实践是检验真理的唯一标准,的确如此. 自己一直比较懒,虽然觉得大牛应该一个记事本全部搞定,但自己还是喜欢用Dw或者Vs写好网页的架构,因为总觉得用notepad还要自己导入声明,而gVim还没有 ...