且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

《深入理解JavaScript》——1.14 对象和构造函数

更新时间:2022-10-13 11:04:18

本节书摘来自异步社区《深入理解JavaScript》一书中的第1章,第1.14节,作者: 【美】AxelRauschmayer(罗彻麦尔)译者: 王玉林 , 杜欢 , 庄婷婷 , 章子鹏,更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.14 对象和构造函数

本节涵盖了JavaScript两种基础的面向对象机制:单一对象和构造函数(类似其他语言中对象的工厂方法)。

1.14.1 单一对象
和所有的值一样,对象也具有属性。你可以认为对象是一组属性的集合,事实也是如此,每个属性都是一个(键,值)对。键名都是字符串,而值可以是JavaScript的任意值。

在JavaScript中,可以直接通过对象字面量去创建普通对象:

  《深入理解JavaScript》——1.14 对象和构造函数

上述对象具有name和describe两个属性。你可以获取(get)以及设置(set)这些属性:

  《深入理解JavaScript》——1.14 对象和构造函数

以函数作为值的属性被称为方法,如describe。它们使用this对调用它们的对象进行引用:

  《深入理解JavaScript》——1.14 对象和构造函数

使用in运算符检查属性是否存在:

  《深入理解JavaScript》——1.14 对象和构造函数

如果读取一个不存在的属性,会得到undefined。因此,之前的两个检查可以这样执行:

  《深入理解JavaScript》——1.14 对象和构造函数

使用delete运算符移除属性:

  .《深入理解JavaScript》——1.14 对象和构造函数

1.14.2 任意属性名
属性的键名可以是任何字符串。迄今为止,我们见到过对象字面量中的属性名和点运算符后的属性名。然而,只有当它们是标识符的时候才可以这样使用(参见1.3.3“标识符与变量名”)。如果想用其他的字符串作为属性名,则必须将它们用引号引起来,再通过对象字面量和方括号来获取或设置这个属性:

《深入理解JavaScript》——1.14 对象和构造函数

方括号可以用来动态计算属性键名:

  《深入理解JavaScript》——1.14 对象和构造函数

1.14.3 提取方法
如果对方法进行提取,则会失去与对象的连接。就这个函数而言,它不再是一个方法,this的值也会是undefined(在严格模式下)。

看如下示例,先回到之前的jane对象:

  《深入理解JavaScript》——1.14 对象和构造函数

我们要从jane对象中提取describe方法,将它赋值给变量func,然后对它进行调用。你会发现,它不能正常运行:

  《深入理解JavaScript》——1.14 对象和构造函数

处理这个问题的解决方案可以使用bind()方法,所有函数都支持。它会创建一个this总是指向给定值的新函数:

  《深入理解JavaScript》——1.14 对象和构造函数

1.14.4 方法中的函数
所有函数都有其特殊的this变量。如果在方法中有嵌套函数,这可能会不太方便,因为在嵌套函数内部不能访问方法中的this变量。下面这个例子展示了调用forEach并结合一个函数来遍历数组:

  《深入理解JavaScript》——1.14 对象和构造函数

调用logHiToFriends会产生一个错误:

 《深入理解JavaScript》——1.14 对象和构造函数

让我们来看看这个问题的两种解决方法。第一种,我们可以将this保存在不同的变量中:

  《深入理解JavaScript》——1.14 对象和构造函数

第二种,利用forEach的第二个参数,它可以给this指定一个值:

  《深入理解JavaScript》——1.14 对象和构造函数

函数表达式在JavaScript中通常被当作函数调用中的参数来使用。在这些函数表达式中引用this时要特别小心。

1.14.5 构造函数:对象工厂
到现在为止,JavaScript对象字面量表现出的那种类似于其他语言中映射表/字典的印象,可能会使你觉得JavaScript对象仅仅是字符串到值的映射。然而,JavaScript对象也支持真正的面向对象:继承。本节不会去完全解释JavaScript的继承是如何工作的,而会展示一种简单的模式让你快速上手。想了解更多详情,请查看第17章。

除了“真正的”函数和方法,函数在JavaScript中还扮演了另外一个角色:如果用new运算符来调用的话,它们将变成构造函数即对象工厂。构造函数就是这样简单地模拟了其他语言的类。按照惯例,构造函数的名称以大写字母开头。例如:

  《深入理解JavaScript》——1.14 对象和构造函数

可以看到构造函数包含两部分。第一部分,Point函数设置实例数据。第二部分,Point.prototype属性包含一个带有方法的对象。第一部分里的实例数据是特定于每一个实例的,而之后的方法数据则是对所有实例共享的。

可以通过new运算符来使用Point:

  《深入理解JavaScript》——1.14 对象和构造函数

p是Point的一个实例:

  《深入理解JavaScript》——1.14 对象和构造函数