单一物件
像所有值一样,对象也具有属性。实际上,您可以将一个对象视为一组属性,其中每个属性都是(键,值)对。键是一个字符串,值是任何JavaScript值。
在JavaScript中,您可以通过对象常量直接创建普通对象:
'use strict';
var jane = {
name: 'Jane',
describe: function () {
return 'Person named '+this.name;
}
};
前面的对象具有name和的属性describe。您可以读取(“获取”)和写入(“设置”)属性:
> jane.name //获取
简
> jane.name ='John'; //设定
> jane.newProperty ='abc'; //自动创建的属性
函数值属性,例如如describe被称为方法。它们用于this引用用于调用它们的对象:
> jane.describe()//调用方法
“叫约翰的人”
> jane.name ='Jane';
> jane.describe()
“人叫简”
该in运营商检查是否一个属性是否存在:
>简中的“ newProperty”
真正
>简中的“ foo”
假
如果读取的属性不存在,则会得到值undefined。因此,前面的两个检查也可以这样执行:[ 2 ]
> jane.newProperty!==未定义
真正
> jane.foo!==未定义
假
该delete运营商删除一个属性:
>删除jane.newProperty
真正
>简中的“ newProperty”
假
任意属性键
属性键可以是任何字符串。到目前为止,我们已经在对象文字中和点运算符之后看到了属性键。但是,只有当它们是标识符时,您才能以这种方式使用它们(请参阅标识符和变量名)。如果要使用其他字符串作为键,则必须在对象文字中用引号将它们引起来并使用方括号来获取和设置属性:
> var obj = {'非标识符':123};
> obj ['非标识符']
123
> obj ['not a identifier'] = 456;
方括号还允许您计算属性的键:
> var obj = {hello:'world'};
> var x ='hello';
> obj [x]
'世界'
> obj ['hel'+'lo']
'世界'
提取方法
如果提取方法,则该方法将失去与对象的连接。该函数本身不再是方法,而是具有值(在严格模式下)。thisundefined
作为示例,让我们回到先前的对象jane:
'use strict';
var jane = {
name: 'Jane',
describe: function () {
return 'Person named '+this.name;
}
};
我们describe要从中提取方法jane,将其放入变量中func,然后调用它。但是,这不起作用:
> var func = jane.describe;
> func()
TypeError:无法读取未定义的属性“名称”
解决方案是使用所有功能都具有的方法bind()。它创建一个this始终具有给定值的新函数:
> var func2 = jane.describe.bind(jane);
> func2()
“人叫简”
方法内部的功能
每个功能都有 它自己的特殊变量this。如果您将一个函数嵌套在一个方法内部,这是很不方便的,因为您无法this从该函数访问该方法。下面是一个示例,其中我们forEach使用一个函数来遍历数组:
var jane = {
name: 'Jane',
friends: [ 'Tarzan', 'Cheeta' ],
logHiToFriends: function () {
'use strict';
this.friends.forEach(function (friend) {
// `this` is undefined here
console.log(this.name+' says hi to '+friend);
});
}
}
调用logHiToFriends会产生错误:
> jane.logHiToFriends()
TypeError:无法读取未定义的属性“名称”
让我们看一下解决此问题的两种方法。首先,我们可以存储this在另一个变量中:
logHiToFriends: function () {
'use strict';
var that = this;
this.friends.forEach(function (friend) {
console.log(that.name+' says hi to '+friend);
});
}
或者,forEach还有第二个参数,可让您提供以下值this:
logHiToFriends: function () {
'use strict';
this.friends.forEach(function (friend) {
console.log(this.name+' says hi to '+friend);
}, this);
}
函数表达式通常在JavaScript中用作函数调用的参数。当您this从这些函数表达式之一进行引用时,请务必小心。
构造函数:对象工厂
到现在为止,您可能会认为 JavaScript对象只是从字符串到值的映射,这是JavaScript的对象文字所建议的一种概念,看起来像其他语言的map / dictionary文字。但是,JavaScript对象还支持一种真正面向对象的功能:继承。本节未完全说明JavaScript继承的工作原理,但向您展示了一种入门的简单模式。如果您想了解更多,请查阅第17章。
除了是“真实的”函数和方法之外,函数在JavaScript中还扮演着另一个角色:如果通过运算符调用,它们将成为构造函数(对象的工厂)new。因此,构造函数大致类似于其他语言的类。按照约定,构造函数的名称以大写字母开头。例如:
// Set up instance data
function Point(x, y) {
this.x = x;
this.y = y;
}
// Methods
Point.prototype.dist = function () {
return Math.sqrt(this.x*this.x + this.y*this.y);
};
我们可以看到构造函数有两个部分。首先,该函数Point设置实例数据。其次,属性Point.prototype包含一个带有方法的对象。前者数据特定于每个实例,而后者数据在所有实例之间共享。
要使用Point,我们通过运算符调用它:new
> var p =新Point(3,5);
>像素
3
> p.dist()
5.830951894845301
p是的实例Point:
> p instanceof点
真正