gpt4 book ai didi

JavaScript的new关键字

转载 作者:行者123 更新时间:2023-11-30 06:59:28 24 4
gpt4 key购买 nike

原问题:What is the ‘new’ keyword in JavaScript?

通常,JavaScript初学者在看过new关键字的讲解之后会陷入迷惑之中。因为JavaScript不是一个OOP语言,而传统的new关键字是用来创建一个对象的。接着,当看到很多书上讲到prototypeprototype.constructor的时候,更迷惑了:这个constructor是几个意思?

现在由new关键字为契机,说一下JavaScript中的对象和OOP。

内存和new

虽然说JavaScript不是面向对象的编程语言,但程序总归还是在内存里运行的。不管编程语言有没有对象的概念,最终还是要跟内存打交道。

那么问题来了:一个JavaScript程序在内存中运行的时候,内存是怎样一种状况呢?

不走得太深,我们规定场景为:浏览器打开一个web页面,该页面中的JavaScript程序的运行情况。

一般情况下,内存中会是以下场景:

  • window对象,全局的
  • 栈,函数调用时使用
  • 堆,使用new关键字申请

那么答案来了:new关键字是用来申请内存的。

对象和new

又重复一遍:JavaScript不是面向对象的编程语言。这句话中的面向对象指的是:封装、继承、多态。实际上这句话是废话,没有任何意义,建议以后忘掉它。

实际上JavaScript中处处都是对象——JSON对象。Object/Attribute, Function/Method的实例通通都是一个JSON对象。

与其他编程语言一样,使用new关键字可以创建一个新对象,也就是一个Object的实例,一个JSON实例。

实例展示:JSFiddle

function Foo(){
this.bar = 'foo bar';
}

/** 在内存创建了一个新的JSON对象
*{
* bar: 'foo bar',
* __proto__: {
* constructor: {name: 'Foo', ...},
* __proto__
* }
*}
**/
var foo = new Foo();

console.log(JSON.stringify(foo)); // 输出: {"bar":"foo bar"}

// 输出: bar foo bar
for(var propName in foo) {
propValue = foo[propName]
console.log(propName,propValue);
}

深入JavaScript对象

其实没什么好深入的,就是在MCMAScript中对这个JSON对象有几个特别的规定:ECMAScript- Object

  • prototype属性
  • constructor属性
  • hasOwnProperty(property)方法
  • propertyIsEnumerable(property)方法

这几个特别属性和方法,请参考文档中的说明。其实这几个规定的目的,也是为了完善创建出来的JSON对象的属性列表,使其具有任意扩展、属性继承的效果。

使用prototype来任意扩展可访问的JSON属性,看一个例子:JSFiddle

function Foo(){
this.bar = 'foo bar';
}
Foo.prototype.b = 'foo bar b'; // 给Foo.prototype属性赋值

/** 在内存创建了一个新的JSON对象
*{
* bar: 'foo bar',
* __proto__: {
* b: 'foo bar b';
* constructor: {name: 'Foo', ...},
* __proto__
* }
*}
**/
var foo = new Foo();

debugger;

console.log(JSON.stringify(foo)); // 还是输出: {"bar":"foo bar"}

// 输出: bar foo bar
// b foo bar b
for(var propName in foo) {
propValue = foo[propName]
console.log(propName,propValue);
}

使用prorotype扩展属性

至于使用prototype实现继承效果,不详细解释。这里给出一般使用的extend()方法的定义,再来一个使用实例:JSFiddle

var extend = function (Base) {
var Class = function () {
Base.apply(this, arguments);
}, F;
if (Object.create) {
Class.prototype = Object.create(Base.prototype);
} else {
F = function () {};
F.prototype = Base.prototype;
Class.prototype = new F();
}
Class.prototype.constructor = Class;
return Class;
};

使用prorotype继承属性

不使用new呢?

如果不使用new关键字,那就是函数调用。本质上就是执行内存中window对象的代码。

而函数定义这个操作,本身就是给window这个JSON对象添加成员。

比如

// 以下函数定义的实质是window.Foo = function{}
var Foo = function(){
this.A = 1;
this.B = 2;
};

Foo(); // 将会对`window`对象添加两个属性A和B。因为此时this指向的内存是`window`

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com