Difference between methods of defining JavaScript 'class
Difference between methods of defining JavaScript 'classes'
这两种在JavaScript中定义"class"的方法有什么区别?
方法一
在构造函数中定义方法:
function MyClass()
{
this.foo = function() { console.log('hello world!'); };
}
方法二
在原型上定义方法:
function MyClass()
{}
MyClass.prototype.foo = function() { console.log('hello world!'); };
第一个将在对象的每个实例化上创建一个新的函数对象,第二个将为每个实例分配一个对原型方法的引用。简而言之:第二个更有效,因为所有实例都将共享一个函数对象。
这只是原型链的逻辑,您可以尝试并通过任何对象访问任何内容:
var objLiteral = {foo:'bar'};
访问objLiteral.foo
时,JS将首先查看对象本身定义的属性,如果找到该值,则返回该值。如果JS找不到对象本身的属性,它将检查对象的原型,因此:
objLiteral.valueOf();//method defined @Object.prototype
objLiteral.valueOf === Object.prototype.valueOf //true
但当你使用第一种方法时:
function SomeConstructor()
{
this.methd = function()
{
return true;
}
}
var f = new SomeConstructor();
var g = new SomeConstructor();
f.methd === g.methd;//FALSE!
这表明我们正在处理两个独立的函数对象。将函数定义移动到原型,f.methd === g.methd;
将为真:
function SomeConstructor()
{
}
SomeConstructor.prototype.methd = function()
{
return true;
}
var f = new SomeConstructor();
var g = new SomeConstructor();
f.methd === g.methd;//true!
回复您的评论:
在原型级别上定义方法允许您更改特定任务的方法,然后将其"重置"为默认行为。假设您所在的函数正在创建AJAX请求:
someObject.toString = function(){ return JSON.stringify(this);}
//when concatinating this object you'll get its json string
//do a lot of stuff
delete (someObject.toString);
JS将再次检查对象是否在其自身上定义了toString
属性。因此JS将删除您分配给toString
属性的函数。下次调用toString
时,JS将重新开始扫描原型链,并使用该方法(在原型中)的第一次出现。让我们澄清一下:
function SomeConstructor()
{
}
SomeConstructor.prototype.methd = function()
{
return true;
}
var f = new SomeConstructor();
var g = new SomeConstructor();
f.methd = function(){return false;};
g.methd();//returns true, still <-- method is gotten from the prototype
f.methd();//returns false <-- method is defined @ instance level
delete (f.methd);
f.methd();//returns true, f doesn't have the method, but the prototype still does, so JS uses that.
或者更好的是,您甚至可以用另一个原型的方法替换实例的方法:
f.methd = Object.prototype.valueOf;//for as long as you need
最后一个例子毫无意义,因为f已经有了valueOf
方法:它的继承链看起来像这样:var f ---> SomeConstructor ---> Object
,也允许您访问所有Object.prototype方法!整洁,不是吗?
这些只是虚设的例子,但我希望你能看到,这是使JS成为一种极其灵活(有时我必须承认,过于灵活)和富有表现力的语言的特性之一。
在第一种情况下,将为每个实例创建函数,并将其设置为对象中的foo
属性。在第二种情况下,它是共享函数。当你调用obj.prop
时,它会在对象本身中查找它,如果它不在那里,那么它会在proto
对象中查找,依此类推,它被称为chain of prototypes
。
例如,此代码提供foo
:
function MyClass() {
this.foo = function () {};
}
var myVariable = new MyClass();
for (var i in myVariable) if (myVariable.hasOwnProperty(i)) console.log(i);
但这不是:
function MyClass() {
}
MyClass.prototype.foo = function () {};
var myVariable = new MyClass();
for (var i in myVariable) if (myVariable.hasOwnProperty(i)) console.log(i);
- javascript点击函数不;不适用于ID和Class
- Difference between methods of defining JavaScript 'class
- Javascript add class 不起作用
- Class.create()上的Comatose(rails插件)javascript错误
- JavaScript-从匹配的img标题中删除Class
- Javascript对象Class节点
- JavaScript对象中的[[Class]]属性
- 使用javascript bookmarklet查找和替换网页上class属性中的文本
- Javascript get "this" class with onClick function
- JQuery .extend() and Javascript class
- javascript oop, instanceof and base class
- 在页面加载jQuery/Javascript时,按.class对表行进行排序
- 将class属性设置为元素不适用于javascript和jquery
- 未定义Javascript对象Class错误
- 如何从javascript访问html的STYLE标记中的class属性
- Javascript if active element's的值等于add class
- JavaScript id + class vs. class selector performance
- Javascript:将 AJAX 结果保存为 Class 变量
- AngularJS ng-class JavaScript animations不会触发
- active class javascript