构造函数
JavaScript 中的构造函数和其它语言中的构造函数是不同的。
通过 new
关键字方式调用的函数都被认为是构造函数。
在构造函数内部 - 也就是被调用的函数内 - this
指向新创建的对象 Object
。
这个新创建的对象的 prototype
被指向到构造函数的 prototype
。
如果被调用的函数没有显式的 return
表达式,则隐式的会返回 this
对象 - 也就是新创建的对象。
function Foo() {
this.bla = 1;
}
Foo.prototype.test = function() {
console.log(this.bla);
};
var test = new Foo();
上面代码把 Foo
作为构造函数调用,并设置新创建对象的 prototype
为 Foo.prototype
。
显式的 return
表达式将会影响返回结果,但仅限于返回的是一个对象。
function Bar() {
return 2;
}
new Bar(); // 返回新创建的对象
function Test() {
this.value = 2;
return {
foo: 1
};
}
new Test(); // 返回的对象
译者注:new Bar()
返回的是新创建的对象,而不是数字的字面值 2。
因此 new Bar().constructor === Bar
,但是如果返回的是数字对象,结果就不同了,如下所示
function Bar() {
return new Number(2);
}
new Bar().constructor === Number
译者注:这里得到的 new Test()
是函数返回的对象,而不是通过new
关键字新创建的对象,因此:
(new Test()).value === undefined
(new Test()).foo === 1
如果 new
被遗漏了,则函数不会返回新创建的对象。
function Foo() {
this.bla = 1; // 获取设置全局参数
}
Foo(); // undefined
虽然上例在有些情况下也能正常运行,但是由于 JavaScript 中 this
的工作原理,
这里的 this
指向全局对象。
工厂模式
为了不使用 new
关键字,构造函数必须显式的返回一个值。
function Bar() {
var value = 1;
return {
method: function() {
return value;
}
}
}
Bar.prototype = {
foo: function() {}
};
new Bar();
Bar();
上面两种对 Bar
函数的调用返回的值完全相同,一个新创建的拥有 method
属性的对象被返回,
其实这里创建了一个闭包。
还需要注意, new Bar()
并不会改变返回对象的原型(译者注:也就是返回对象的原型不会指向 Bar.prototype
)。
因为构造函数的原型会被指向到刚刚创建的新对象,而这里的 Bar
没有把这个新对象返回(译者注:而是返回了一个包含 method
属性的自定义对象)。
在上面的例子中,使用或者不使用 new
关键字没有功能性的区别。
译者注:上面两种方式创建的对象不能访问 Bar
原型链上的属性,如下所示:
var bar1 = new Bar();
typeof(bar1.method); // "function"
typeof(bar1.foo); // "undefined"
var bar2 = Bar();
typeof(bar2.method); // "function"
typeof(bar2.foo); // "undefined"
通过工厂模式创建新对象
我们常听到的一条忠告是不要使用 new
关键字来调用函数,因为如果忘记使用它就会导致错误。
为了创建新对象,我们可以创建一个工厂方法,并且在方法内构造一个新对象。
function Foo() {
var obj = {};
obj.value = 'blub';
var private = 2;
obj.someMethod = function(value) {
this.value = value;
}
obj.getPrivate = function() {
return private;
}
return obj;
}
虽然上面的方式比起 new
的调用方式不容易出错,并且可以充分利用私有变量带来的便利,
但是随之而来的是一些不好的地方。
- 会占用更多的内存,因为新创建的对象不能共享原型上的方法。
- 为了实现继承,工厂方法需要从另外一个对象拷贝所有属性,或者把一个对象作为新创建对象的原型。
- 放弃原型链仅仅是因为防止遗漏
new
带来的问题,这似乎和语言本身的思想相违背。
总结
虽然遗漏 new
关键字可能会导致问题,但这并不是放弃使用原型链的借口。
最终使用哪种方式取决于应用程序的需求,选择一种代码书写风格并坚持下去才是最重要的。
相关推荐
构造函数 this 指向:1 构造函数 this 指的是对象实例2 原型对象函数里面也 this 也是指向实例对象// 构造函数function Student
javascript-数学函数Maths.rar
JavaScript应用实例-常用函数-小七.js
### JavaScript组合使用构造函数模式和原型模式实例解析 #### 一、引言 在JavaScript编程中,构造函数模式和原型模式是两种常见的面向对象编程(OOP)方式。这两种模式各有优势,结合使用能够更好地实现代码复用和...
在JavaScript中,构造函数和原型链是实现面向对象编程的核心机制。它们共同构成了JavaScript的类继承模型。让我们深入探讨这两个概念及其之间的关系。 1. 构造函数(Constructor): - 构造函数是一种特殊类型的...
在JavaScript中,构造函数是一种特殊类型的函数,用于初始化创建对象。构造函数经常被用于创建具有相似属性和方法的多个对象。JavaScript中构造函数和实例对象之间的关系,以及其背后的原理是JavaScript编程中的一个...
JavaScript函数-高级教程.md
在JavaScript中,构造函数是一种特殊类型的函数,主要用于创建和初始化对象。当使用`new`关键字调用构造函数时,它会执行以下步骤: 1. 创建一个新的空对象。 2. 将这个新对象的[[Prototype]]链接到构造函数的原型...
第16周-第10章节-Python3.5-JavaScript函数.avi
在JavaScript中,类(Class)、对象(Object)和构造函数(Constructor)是面向对象编程的基础。这篇文章将深入探讨这三个概念,以及如何实现类的继承。 首先,让我们理解什么是JavaScript中的对象。在JavaScript中...
在JavaScript中,构造函数和原型对象的继承是实现面向对象编程的重要机制。JavaScript是一种基于原型的语言,这意味着对象可以直接从其他对象继承属性和方法。这里我们将深入探讨这两种概念以及它们如何协同工作来...
//父级-构造函数 function Father() { this.fatherProp = true } //父级-原型属性 Father.prototype.getFatherValue = function() { return this.fatherProp } //子级-构造函数 function Son() { this.sonProp =
### JavaScript对象、原型、属性、构造函数、扩展、JSON #### JavaScript对象类型 JavaScript是一种广泛使用的脚本语言,尤其在Web开发中占据了重要的地位。它支持多种对象类型,包括内部对象、基于类的对象以及...
1. 原型与继承:JavaScript的继承是基于原型链实现的,构造函数、__proto__属性和Object.create()方法是实现继承的关键。 2. 扩展运算符与解构赋值:这两种语法糖极大提升了代码的简洁性和可读性,分别用于复制对象...
通过字面量语法或构造函数可以创建对象,原型链则用于实现继承。理解原型和原型链的概念对于深入掌握JavaScript面向对象编程至关重要。 事件和DOM操作是JavaScript与用户交互的基础。事件是用户与网页互动时发生的...
- **构造函数创建对象**:使用`new`关键字和`Object`构造函数来创建对象,或者自定义构造函数。 - **工厂模式**:工厂函数是一个返回对象的函数,可以创建具有相同属性和方法的不同对象,体现了面向对象的理念。 - *...
在JavaScript中,可以使用多种方法创建新对象,包括使用对象字面量、构造函数以及ES6中引入的类。 - **对象字面量**:通过直接写明属性和值来创建对象。 - **构造函数**:定义一个函数并在其中设置对象的属性和方法...
- **面向对象**:尽管JavaScript没有传统意义上的类,但它支持基于原型的面向对象编程方式,可以通过构造函数和原型链来实现继承。 - **事件驱动**:JavaScript的核心之一在于处理用户的交互事件,如点击、滑动等。 ...
很显然,这个时候obj的constructor已经不再是创建它的函数,注意到obj.name也是undefined,因此修改构造函数的prototype的contructor并不会影响构造函数所产生的对象。真正的原因是:一个对象的constructor是它的...