我不知道最好的方法是创建具有属性和方法的JavaScript对象。
我看过一些示例,该示例中的人员使用var self = this
然后self.
在所有功能中使用以确保范围始终正确。
然后,我看到了.prototype
用于添加属性的示例,而其他示例则是内联的。
有人可以给我一个带有某些属性和方法的JavaScript对象的正确示例吗?
我不知道最好的方法是创建具有属性和方法的JavaScript对象。
我看过一些示例,该示例中的人员使用var self = this
然后self.
在所有功能中使用以确保范围始终正确。
然后,我看到了.prototype
用于添加属性的示例,而其他示例则是内联的。
有人可以给我一个带有某些属性和方法的JavaScript对象的正确示例吗?
Closure
是多功能的。在创建对象时,bobince很好地总结了原型与封闭方法。但是,您可以模仿OOP
以功能编程方式使用闭包的某些方面。记住函数是JavaScript中的对象 ; 因此以不同的方式将函数用作对象。
这是关闭的示例:
function outer(outerArg) {
return inner(innerArg) {
return innerArg + outerArg; //the scope chain is composed of innerArg and outerArg from the outer context
}
}
前一段时间,我碰到了Mozilla关于Closure的文章。这就是我的看法:“闭包可让您将某些数据(环境)与对该数据进行操作的函数相关联。这与面向对象编程(其中对象允许我们将某些数据(对象的属性)相关联”具有明显的相似之处。)使用一种或多种方法 ”。这是我第一次阅读闭包与经典OOP之间的并行性,而没有引用原型。
怎么样?
假设您要计算某些商品的增值税。增值税可能会在申请有效期内保持稳定。在OOP(伪代码)中执行此操作的一种方法:
public class Calculator {
public property VAT { get; private set; }
public Calculator(int vat) {
this.VAT = vat;
}
public int Calculate(int price) {
return price * this.VAT;
}
}
基本上,您将VAT值传递给构造函数,然后您的calculate方法可以通过闭包对其进行操作。现在,不使用类/构造函数,而是将VAT作为参数传递给函数。因为您唯一感兴趣的是计算本身,所以返回一个新函数,即calculate方法:
function calculator(vat) {
return function(item) {
return item * vat;
}
}
var calculate = calculator(1.10);
var jsBook = 100; //100$
calculate(jsBook); //110
在您的项目中,确定最适合用来计算增值税的顶级值。根据经验,每当您不断传递相同的参数时,就有一种使用闭包改进它的方法。无需创建传统对象。
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Closures
除了2009年接受的答案。如果您可以针对现代浏览器,则可以使用Object.defineProperty。
Object.defineProperty()方法直接在对象上定义新属性,或修改对象上的现有属性,然后返回对象。资料来源:Mozilla
var Foo = (function () {
function Foo() {
this._bar = false;
}
Object.defineProperty(Foo.prototype, "bar", {
get: function () {
return this._bar;
},
set: function (theBar) {
this._bar = theBar;
},
enumerable: true,
configurable: true
});
Foo.prototype.toTest = function () {
alert("my value is " + this.bar);
};
return Foo;
}());
// test instance
var test = new Foo();
test.bar = true;
test.toTest();
要查看桌面和移动设备兼容性列表,请参见Mozilla的浏览器兼容性列表。是的,IE9 +和Safari移动版都支持它。
当在构造函数调用过程中使用关闭“ this”的技巧时,是为了编写一个函数,该函数可以被其他不想在该对象上调用方法的对象用作回调。它与“使范围正确”无关。
这是一个普通的JavaScript对象:
function MyThing(aParam) {
var myPrivateVariable = "squizzitch";
this.someProperty = aParam;
this.useMeAsACallback = function() {
console.log("Look, I have access to " + myPrivateVariable + "!");
}
}
// Every MyThing will get this method for free:
MyThing.prototype.someMethod = function() {
console.log(this.someProperty);
};
您可能会从阅读道格拉斯·克罗克福德(Douglas Crockford)关于JavaScript的内容中学到很多。约翰·雷西格(John Resig)也很聪明。祝好运!
在es6中,您现在可以实际创建一个 class
现在,您可以执行以下操作:
class Shape {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return `Shape at ${this.x}, ${this.y}`;
}
}
因此,可以延伸到一个圆圈(如其他答案所示):
class Circle extends Shape {
constructor(x, y, r) {
super(x, y);
this.r = r;
}
toString() {
let shapeString = super.toString();
return `Circular ${shapeString} with radius ${this.r}`;
}
}
最终在es6中变得更干净,更易于阅读。
这是一个有效的例子:
class Shape {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return `Shape at ${this.x}, ${this.y}`;
}
}
class Circle extends Shape {
constructor(x, y, r) {
super(x, y);
this.r = r;
}
toString() {
let shapeString = super.toString();
return `Circular ${shapeString} with radius ${this.r}`;
}
}
let c = new Circle(1, 2, 4);
console.log('' + c, c);
您也可以使用结构以这种方式进行操作:
function createCounter () {
var count = 0;
return {
increaseBy: function(nb) {
count += nb;
},
reset: function {
count = 0;
}
}
}
然后 :
var counter1 = createCounter();
counter1.increaseBy(4);
我相当频繁地使用此模式-我发现它在需要时为我提供了极大的灵活性。在使用中,它非常类似于Java风格的类。
var Foo = function()
{
var privateStaticMethod = function() {};
var privateStaticVariable = "foo";
var constructor = function Foo(foo, bar)
{
var privateMethod = function() {};
this.publicMethod = function() {};
};
constructor.publicStaticMethod = function() {};
return constructor;
}();
这将使用创建时调用的匿名函数,并返回一个新的构造函数。由于匿名函数仅被调用一次,因此您可以在其中创建私有静态变量(它们在闭包内部,对于该类的其他成员可见)。构造函数基本上是一个标准的Javascript对象-您在其中定义私有属性,并将公共属性附加到this
变量中。
基本上,这种方法将Crockfordian方法与标准Javascript对象结合在一起,以创建功能更强大的类。
您可以像使用其他任何Javascript对象一样使用它:
Foo.publicStaticMethod(); //calling a static method
var test = new Foo(); //instantiation
test.publicMethod(); //calling a method
创建一个对象
在JavaScript中创建对象的最简单方法是使用以下语法:
这对于以结构化方式存储数据非常有用。
但是,对于更复杂的用例,通常最好创建函数实例:
这使您可以创建共享相同“蓝图”的多个对象,类似于您在例如中使用类的方式。Java。
但是,仍然可以通过使用原型来更高效地完成此操作。
每当函数的不同实例共享相同的方法或属性时,就可以将它们移至该对象的原型。这样,函数的每个实例都可以访问该方法或属性,但是不必为每个实例都复制它。
In our case, it makes sense to move the method
f
to the prototype :Inheritance
A simple but effective way to do inheritance in JavaScript, is to use the following two-liner :
That is similar to doing this :
The main difference between both is that the constructor of
A
is not run when usingObject.create
, which is more intuitive and more similar to class based inheritance.You can always choose to optionally run the constructor of
A
when creating a new instance ofB
by adding adding it to the constructor ofB
:If you want to pass all arguments of
B
toA
, you can also useFunction.prototype.apply()
:If you want to mixin another object into the constructor chain of
B
, you can combineObject.create
withObject.assign
:Demo
Note
Object.create
可以在包括IE9 +在内的所有现代浏览器中安全使用。Object.assign
不适用于任何版本的IE或某些移动浏览器。建议使用polyfillObject.create
和/或Object.assign
如果要使用它们并支持未实现它们的浏览器。你可以找到一个填充工具对
Object.create
这里 和一个Object.assign
在这里。