首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

你的手写 new 实现足够严谨吗?

基本上,上面代码的实现没有什么问题,但是我突然产生了一个疑问:当第一个参数是 null 的时候,Fn.prototype = proto 已经把构造函数的原型对象设置为 null了,为什么后面还要在判断第一个参数为...这就能解释为什么用 null 重写构造函数的原型后,实例的 __proto__ 没有跟着改变了,因为在调用构造函数的过程,它链接上了 Object.prototype,可以说,这里实例的原型链并没有断开...有的实现甚至直接使用Object.create() 方法以快速地建立原型关系,就像这样: function myNew(Fn,...args){ if(typeof Fn !...returnValue : instance } 这里直接使用Object.create() 方法,是有问题的。...在前面阅读规范的时候我们已经知道了,即使传给 Object.create 的参数是 null,也会将其作为创建的对象的 __proto__,所以这里如果使用Object.create,并且构造函数的原型

49710

JavaScript 面试要点: 继承

很多面向对象语言都支持两种继承:接口继承和实现继承。前者只继承方法签名,后者继承实际的方法。接口继承在 ECMAScript 是不可能的,因为函数没有签名。...这也是为什么自定义类型能够继承包括 toString()、 valueOf() 在内的所有默认方法的原因。 # 原型与继承关系 原型与实例的关系可以通过两种方式来确定。...原型包含引用值的时候,原型包含的引用值会在所有实例间共享 所以属性通常会在构造函数定义而不会定义在原型上的原因。...原型式继承非常适合不需要单独创建构造函数,但仍然需要在对象间共享信息的场合。但要记住,属性包含的引用值始终会在相关对象间共享,跟使用原型模式是一样的。...本质上,子类原型最终是要包含超类对象的所有实例属性,子类构造函数只要在执行时重写自己的原型就行了。

15710
您找到你想要的搜索结果了吗?
是的
没有找到

Javascript Prototypes之旅(A Plain English Guide to JavaScript Prototypes译文)

(译者语:在对象已找到了相应的属性,那么就不会将消息转发到原型去) 6. Object.create   前面已经说过__proto__属性并非设置原型的标准方法。...下面我们使用Object.create方法来创建对象并指定该对象的原型。该方法在ES5可用,但老的浏览器和JS引擎要通过es5-hhim来使用了。 ?...(译者语:我们甚至可以通过object.create(null)开创建一个没有原型的对象;而使用其他方式创建的对象它的原型至少有一个Object类实例) 当然在创建对象的时候,还可以设置该对象的属性...注意:这个隐式创建的this对象,当且仅当使用关键字new创建函数实例时出现,若不使用关键字new就会就会出现不可预知的问题,一般情况下为以首字母大写的方式来命名构造函数,以提示使用关键字new来调用该函数...__proto__和prototype属性的关系其实很简单,prototype属性所指向的原型会在使用关键字new调用构造函数时被复制到隐式创建的this对象的__proto__

64890

一文读懂 TS Object, object, {} 类型之间的区别

例如,Object.create() 和Object.setPrototypeOf() 方法,现在需要为它们的原型参数指定 object | null 类型: // node_modules/typescript...它由以下两个接口来定义: Object 接口定义了 Object.prototype 原型对象上的属性; ObjectConstructor 接口定义了 Object 类的属性。...Object 类型上定义的所有属性和方法,这些属性和方法可通过 JavaScript 的原型链隐式地使用: // Type {} const obj = {}; // "[object Object...建议实践在 @ts-ignore之后添加相关提示,解释忽略了什么错误。 请注意,这个注释仅会隐藏报错,并且我们建议你少使用这一注释。...它由以下两个接口来定义: 它由以下两个接口来定义: Object 接口定义了 Object.prototype 原型对象上的属性; // node_modules/typescript/lib/lib.es5

15.6K21

JavaScript原型-进阶者指南

好吧,我们可以使用Object.create委托给animalMethods对象,而不是像我们现在一样逐个将所有共享方法添加到动物。...2.如何将方法添加到构造函数的原型。 3.如何使用Object.create将失败的查找委托给函数的原型。 这三个任务似乎是任何编程语言的基础。...数组方法 我们在上面深入讨论了如果要在类的实例之间共享方法,您应该将这些方法放在类(或函数)原型上。如果我们查看Array类,我们可以看到相同的模式。...重新创建Object.create 在这篇文章,非常依赖于Object.create来创建委托给构造函数原型的对象。...为此,我们将使用我们对新关键字和原型如何在JavaScript工作的知识。首先,在Object.create实现的主体内部,我们将创建一个空函数。然后,我们将该空函数的原型设置为等于参数对象。

1.2K50

详解Object.create(null)

在Vue和Vuex的源码,作者都使用Object.create(null)来初始化一个新对象。为什么不用更简洁的{}呢?...大家可能会注意到,第一个参数使用了null。也就是说将null设置成了新创建对象的原型,自然就不会有原型链上的属性。...Object.create(null)的使用场景 再回到文章开头的问题,为什么很多源码作者会使用Object.create(null)来初始化一个新对象呢?这是作者的习惯,还是一个最佳实践?...a=Object.create(null) //你可以直接使用下面这种方式判断,因为存在的属性,都将定义在a上面,除非手动指定原型: if(a.toString){} 另一个使用create(null...)的理由是,在我们使用for..in循环的时候会遍历对象原型链上的属性,使用create(null)就不必再对属性进行检查了,当然,我们也可以直接使用Object.keys[]。

85140

JavaScript 原型的深入指南

然后我们所要做的就是不使用Object.create 委托给animalMethods,我们可以用它来委托Animal.prototype。 我们将这种模式称为 原型实例化。...如何向构造函数的原型添加方法。 如何使用 Object.create 将失败的查找委托给函数的原型。 这三个点对于任何编程语言来说都是非常基础的。...如果不使用Object.create创建对象,我们将无法在失败的查找上委托函数的原型。 如果没有return语句,我们将永远不会返回创建的对象。...重写 Object.create 在这篇文章,我们非常依赖于Object.create来创建委托给构造函数原型的对象。...所以在上面的例子,我们用调用Object.create时传入的对象覆盖Fn的原型,我们称之为objToDelegateTo。 请注意,我们只支持 Object.create 的单个参数。

1.1K20

深入理解JavaScript原型:prototype,__proto__和constructor

本文结合笔者开发工作遇到的问题详细讲解JavaScript原型的几个关键概念,如有错误,欢迎指正。 1. JavaScript原型继承 提到JavaScript原型,用处最多的场景便是实现继承。...JavaScript语言中并没有严格意义上的类,本文中提到的类可以理解为一个抽象的概念,原型对象可以理解为类暴露出来的接口。...为什么会得到这样的结果?...JavaScript并没有类的概念,即使ES6规范了class关键字,本质上仍然是基于原型的。类可以作为一个抽象的概念,是为了便于理解构造函数和原型原型可以理解为类暴露出来的一个接口或者属性。...Animal原型而不是赋值修改; 保证派生类构造函数向上递归调用; 使用Object.create()方法而不是寄生式继承; 保证constructor指向的正确性。

77980

JS 原生方法原理探究(二):如何实现 Object.create

ES 规范 对于 Object.create() 的具体实现,规范其实已经描述得很清楚,可以进入http://es5.github.io/#x15.2.3.5查看: ?...不过,我们要留意两个地方: 在这个实现,没有检测第一个参数是不是基本类型的包装对象,只要传进来的参数是对象,我们就认为是合法的 当传入 null 也即 Object.create(null) 的时候,...我们实际上创建了一个很纯粹的空对象,这个对象的原型直接就是 null,Object.prototype 甚至没有出现在该对象的原型,这意味这个对象不会继承 Object 的任何方法。...__proto__ = proto 应该是一样的,为什么要在这种情况下执行一遍 obj.__proto__ = proto 呢?...但根据 Object.create 的实现规范,这里必须让实例的 __proto__ 指向 null,所以才需要执行 obj.__proto__ = proto 去手动设置对象原型

1.8K21

类的继承

本文讲述JavaScript类继承的实现方式,并比较实现方式的差异。 一、何为继承 继承,是子类继承父类的特征和行为,使得子类对象具有父类的实例域和方法。 继承是面向对象编程,不可或缺的一部分。...3.2 将父类的原型传递给子类 Computer.prototype = new Book();使用new操作符对父类Book进行实例化,并将实例对象赋值给子类的prototype。...四、原型式继承 function Computer(){ Book.apply(this, arguments); } Computer.prototype = Object.create(Book.prototype...它的作用是返回一个继承自原型对象Book.prototype的新对象。且该对象下的属性已经初始化。 用Object.create生成新对象,并不会调用到Book的构造函数。...这种方式,也可以通过原型链实现继承。 五、Object.create的简单版兼容 由于低版本的浏览器是不支持Object.create的。

90120

设计模式(7)-JavaScript设计模式之原型模式如何实现???

在其他语言很少使用原型模式,但是JavaScript作为原型语言,在构造新对象及其原型时会使用该模式。 2 参与者 ?...原型( Prototype) :创建一个接口来克隆自己 克隆( Clones ) :正在创建的克隆对象 3 实例讲解 在示例代码,我们有一个CustomerPrototype对象,它可以克隆给定原型对象...返回值:一个新对象,带着指定的原型对象和属性。 4.2 用 Object.create实现继承 下面的例子演示了如何使用Object.create()来实现类式继承。...4.3 使用propertyObject参数 var o; // 创建一个原型为null的空对象 o = Object.create(null); o = {};...尽管在 ES5 Object.create支持设置为[[Prototype]]为null,但因为JS以前一些老版本的限制,此 polyfill 无法支持该特性。

1.2K51

JS原型链与继承别再被问倒了

原文:详解JS原型链与继承 摘自JavaScript高级程序设计: 继承是OO语言中的一个最为人津津乐道的概念.许多OO语言都支持两种继承方式: 接口继承 和 实现继承 .接口继承只继承方法签名,而实现继承则继承实际的方法....由于js中方法没有签名,在ECMAScript无法实现接口继承.ECMAScript只支持实现继承,而且其 实现继承 主要是依靠原型链来实现的....有鉴于此, 实践很少会单独使用原型链. 为此,下面将有一些尝试以弥补原型链的不足....在 ECMAScript5 ,通过新增 object.create() 方法规范化了上面的原型式继承. object.create() 接收两个参数: 一个用作新对象原型的对象 (可选的)一个为新对象定义额外属性的对象...提醒: 原型式继承, 包含引用类型值的属性始终都会共享相应的值, 就像使用原型模式一样. 寄生式继承 寄生式继承是与原型式继承紧密相关的一种思路, 同样是克罗克福德推而广之.

59750

理解原型原型

原型原型链是学习JavaScript这门语言不能不理解的两个重要概念,为什么?因为JavaScript是一门基于原型的语言。 怎么理解“JavaScript是一门基于原型的语言”?...这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。原型模式的目的是用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。...也正是因为这样对象的使用才能更加灵活、更加易于扩展。 原型链: 在javascript,所有的对象都拥有一个__proto__属性指向该对象的原型(prototype)。...使用 for in 循环可以遍历对象所有的属性,包括该对象在原型的属性,如: var A = { a:1, b:2 }; var B = Object.create...为什么?因为C的原型是B,B的原型是A。

55120

前端基础-面向对象核心

; 这个问题,在3.5章节也提到过,想解决也很简单,只要在父级手动指定子级正确的构造函数即可: 修改上面的代码: ?...; 有运行结果可知,f1 函数的this 实际指向了对象b ,对象b 实际上已经继承了f1 这种方式称为 **对象冒充 **方式继承,ES3之前的代码中经常会被使用,但是现在基本不使用了; 为什么使用了呢...Man call或apply 实现的继承依然是使用对象冒充方式实现, 此方式即实现了继承的功能,同时也不再出现原型继承中出现的问题; 6.2.4 Object.create() 创建实例对象及原型继承...我们希望以这个现有的对象作为模板,生成新的实例对象,这时就可以使用Object.create()方法。...' 使用Object.create方法的时候,必须提供对象原型,即参数不能为空,或者不是对象,否则会报错。

29110

原型

根据定义null没有原型,并作为原型链的最后一个环节。 几乎所有JS的对象都是位于原型链顶端的Object的实例 基于原型链的继承 ---- 继承属性 JS对象有一个指向原型对象的链。...f.prototype.c = 4; // 不要在f的原型上直接定义f.prototype = {b:3,c:4};这样会直接破坏原型链 // o....[[prototype]]为null,停止搜索 // 找不到d属性返回undefined 使用不同的方法来创建对象和生成原型链 ---- (1)使用语法结构创建的对象 var o = {a: 1}; /...--> Object.prototype --> null (2)使用构造器创建的对象 在JS,构造器其实就是一个普通的函数,当使用new 操作符来调用这个函数时,他就可以被称为构造方法(构造函数...[[prototype]]指向了Graph.prototype (3)使用Object.create创建的对象 可以调用Object.create()创建一个对象,新对象的原型就是传入的第一个参数。

41420

JavaScript实现继承的6种方式

JavaScript 的继承 继承是面向对象只要的概念,分为接口继承、实现继承。继承接口其实就是继承方法签名,而实现继承是继承实际的方法。...在JavaScript因为函数没有签名,所以实现继承是 ES 唯一的继承方式,其主要是基于原型链来实现的。 1....组合式继承 原型链继承和借用构造函数继承的缺点都比较明显,那我们可以综合原型链继承、借用构造函数继承的优点组合继承。思路是使用原型链继承原型上的属性和方法,借用构造函数继承实例属性。...优点 感觉没啥优点吧,只能说非常适合不需要单独创建构造函数,但仍然需要在对象间共享信息的场合的情况 缺点 原型包含的引用值会在所有实例间共享(修改一个实例的引用类型属性,其他所有实例上的改属性都会跟这变...寄生式组合继承 组合继承的一个缺点是创建子类实例会执行两次构造函数,一次是在创建子类原型上调用了一次,另一次实在子类构造函数调用。

33220
领券