2

可以使用点符号和方括号访问和设置属性(键)。何时使用点原型语法的任何建议

var myObj = {};   
myObj.myProp1 = 'value1'; //works, an expando property   
myObj[myProp2] = 'value2'; // FAILS, myProp2 is undefined
myObj["myProp2"] = 'value2'; // works, an expando property
myObj[2010]= 'value'; //note the key is number, still works, an expando property??   
myObj.2010 = 'value'; // FAILS. to use dot notation, key must be a string

myObj.prototype.myProp3 = 'value3' // whats the advantage?
4

6 回答 6

4

使用点语法时,属性名称是一个标识符:

var myObj = {};
myObj.myProp1 = "value1";
myObj.myProp2 = "value2";

由于属性名称必须遵循标识符命名规则,例如它可以不以数字开头。

使用括号语法时,属性名称是一个字符串:

var myObj = {};
myObj["myProp1"] = "value1";
myObj["myProp2"] = "value2";

括号中使用的可以是变量,也可以是任何类型的产生字符串的表达式:

var myObj = {};
var prop1 = "myProp1";
myObj[prop1] = "value1";
myObj["myProp" + 2] = "value2";

如果您使用数字作为属性名称,它将自动转换为字符串,因此这些具有相同的结果:

myObj[2010] = "value";
myObj["2010"] = "value";

您还可以使用对象文字来设置值:

var myObj = { myProp1: "value1", myProp2: "value2" };

(注意这{}也是一个对象字面量,只是没有属性。)

仅当您已命名对象类型(或以其他方式为对象分配原型)时,使用对象的原型才有用。当您使用对象字面量创建对象时,每个对象都有自己的原型,因此将任何内容放入原型中与将其放入对象中具有相同的效果。

于 2011-01-19T12:26:37.730 回答
1

基本上,通过“。”访问对象的属性没有区别。语法或通过键。

var obj = new function(){this.x = "value";}
警报(obj.x === obj['x']);//它会输出真

有时您不能使用“。” ,因为您尝试访问的属性的名称不是有效的变量名称(正如您用数字键指出的那样):

var obj = new function(){this['my-value'] = "我的价值";}
警报(obj ['我的值']);// 它将输出“我的价值”
警报(obj.my-value);// 它会触发一个异常,因为 javascript
//解释器将“obj.my-value”解释为
//obj的属性“my”减去变量“value”

最大的区别在于浏览器处理您的语法的方式。正如您在此处看到的,我的一个朋友做了一些测试,似乎 Chrome 和 IE 使用点语法运行得更快,而 Firefox 和 Safari 更“热衷于”关键语法。
总之,您几乎每次都可以使用其中任何一个,尽管在某些情况下“。” 有点“措手不及”。

关于原型语法,好吧,当您定义一个对象时,您可以将成员附加到每个实例,但您也可以将成员附加到对象的原型,这意味着每当创建定义类型的新对象时,它将自动继承原型中的那个成员。我认为通过一个例子可以更好地理解:

函数点(x,y){this.x = x;this.y = y;}
Point.prototype.toString = function(){
  return "我是一个点,我的 x 坐标在 "+this.x+",我的 y 坐标在 "+this.y;
}

函数 Point2(x,y){
  这个.x = x;
  这个.y = y;
  this.toString = 函数(){
    return "我也是一个点。我在 x:"+this.x+", y:"+this.y;
  };
}

当您创建 anew Point2时,它的toString方法是一个实例方法,并且 javascript 解释器为此方法分配内存。
当您创建一个“新点”时,它的toString方法将链接在它的原型属性上。这意味着没有为该方法分配内存。

变种 p = [], p2 = [];
for(var i = 0; i < 100000000; i++)
   {
     p.push(新点(0,0));
     p2.push(new Point2(0,0));
   }

如果您对此进行测试,您会发现这两个对象都运行良好,但是您的Point2对象会从系统中占用更多内存。这是为什么?
问题是当你调用 anew Point()toString()方法时,对象意识到它没有一个名为“toString”的成员,它开始在它的原型链上搜索它并返回在对象声明中找到的“toString”成员.
在上面的例子中,所有p's 的项目都将它们的toString方法指向原型中提到的那个,而所有p2' 的项目都将指向它们的每个方法副本。
此外,如果您以后想修改该toString方法,则可以很容易地为所有Point实例修改它:
Point.prototype.toString = function(){return "I'm a smarter point";}; 之后,当你调用它的方法时,每个实例new Point都会返回“I'm a smarter point” 。 如果您尝试为实例修改它,那会有点困难。您会发现这 不会按预期工作,您必须手动更改每个实例的方法: toString
Point2Point2.toString = function(){return "I'm a dumber point";}

for(var i in p2)
  p2[i].toString = function(){return "我是个笨蛋";};

我会让你决定哪种方法更好:P

于 2011-01-19T13:24:42.467 回答
1

在您的情况下,myObj.prototype.myProp3 = 'value3'不应使用,因为对象文字没有原型他们确实有,但他们没有prototype属性(你会看到它myObj.prototype是未定义的)。

原型用于函数new,为使用关键字从该函数构造的所有对象设置默认属性。它不适用于将属性分配给单个对象。

于 2011-01-19T12:15:52.317 回答
1

对我来说,这取决于我将如何使用该对象。

如果我要将它用作关联数组、哈希映射或无法使用点语法的地方,我会使用[and ]

但是,如果我将它们视为对象,我会使用.语法。

于 2011-01-19T13:03:07.400 回答
1

属性添加应该是myObj.myPropmyObj["myProp"]。这是在 javascript 中使用时理想遵循的场景和良好实践。

于 2011-01-19T12:08:26.050 回答
1
var myObj = function () {

};
myObj.prototype.myProp3 = 'value3' // whats the advantage?

如果您想使用 myObj 作为构造来创建多个对象,则应使用此选项。IE 。

var obj1 = new myObj();

那么 obj1 也将获得 myProp3 属性

编辑:编辑了上面的例子。要将 myObj 用作构造函数,应将其声明为函数

于 2011-01-19T12:11:46.707 回答