我想知道创建具有属性和方法的JavaScript对象的最佳方法是什么。
我见过有人用var self = this然后用self的例子。在所有函数中确保作用域总是正确的。
然后我看到了使用.prototype来添加属性的例子,而其他人则是内联的。
谁能给我一个适当的例子,一个JavaScript对象的一些属性和方法?
我想知道创建具有属性和方法的JavaScript对象的最佳方法是什么。
我见过有人用var self = this然后用self的例子。在所有函数中确保作用域总是正确的。
然后我看到了使用.prototype来添加属性的例子,而其他人则是内联的。
谁能给我一个适当的例子,一个JavaScript对象的一些属性和方法?
当前回答
继续鲍恩斯的回答
在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}`;
}
}
最终在es6中更干净,更容易阅读。
下面是一个很好的例子:
类形状{ 构造函数(x, y) { 这一点。X = X; 这一点。Y = Y; } toString () { 返回' Shape at ${this。x} $ {this.y} '; } } 类Circle扩展形状{ 构造函数(x, y, r) { 超级(x, y); 这一点。R = R; } toString () { let shapeString = super.toString(); 返回半径为${this.r}的圆形${shapeString}; } } let c = new Circle(1,2,4); Console.log (" + c, c);
其他回答
我经常使用这种模式——我发现当我需要它的时候,它给了我相当大的灵活性。在使用中,它非常类似于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
你也可以这样做,使用结构:
function createCounter () {
var count = 0;
return {
increaseBy: function(nb) {
count += nb;
},
reset: function {
count = 0;
}
}
}
然后:
var counter1 = createCounter();
counter1.increaseBy(4);
闭包是万能的。Bobince已经很好地总结了创建对象时的原型与闭包方法。但是,您可以用函数式编程的方式使用闭包来模拟OOP的某些方面。记住,函数在JavaScript中是对象;所以用另一种方式使用function作为对象。
这里有一个闭包的例子:
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之间的相似之处。
How?
假设您想要计算某些项目的增值税。增值税可能在应用程序的生命周期内保持稳定。在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值传递给你的构造函数,你的计算方法可以通过闭包对它进行操作。 现在不再使用类/构造函数,而是将VAT作为参数传递到函数中。因为你唯一感兴趣的东西是计算本身,返回一个新函数,这是计算方法:
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/en-US/docs/Web/JavaScript/Guide/Closures
基本上在JS中没有类的概念,所以我们使用函数作为与现有设计模式相关的类构造函数。
//Constructor Pattern
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.doSomething = function(){
alert('I am Happy');
}
}
到目前为止,JS还不知道你想要创建一个对象,所以这里有一个新的关键字。
var person1 = new Person('Arv', 30, 'Software');
person1.name //Arv
参考:专业JS网页开发人员- Nik Z
创建对象
在JavaScript中创建对象最简单的方法是使用以下语法:
Var检验= { A: 5, B: 10, F:函数(c) { 返回。A +这个。B + c; } } console.log(测试); console.log (test.f (3));
这对于以结构化的方式存储数据非常有用。
然而,对于更复杂的用例,创建函数的实例通常更好:
函数测试(a, b) { 这一点。A = A; 这一点。B = B; 这一点。F =函数(c) { 返回。A +这个。B + c; }; } var test = new test (5,10); console.log(测试); console.log (test.f (3));
这允许你创建多个对象共享相同的“蓝图”,类似于你如何使用类在eg。Java。
然而,通过使用原型,这仍然可以更有效地完成。
当一个函数的不同实例共享相同的方法或属性时,您可以将它们移动到该对象的原型中。这样,函数的每个实例都可以访问该方法或属性,但不需要为每个实例复制该方法或属性。
在我们的例子中,将方法f移动到原型中是有意义的:
函数测试(a, b) { 这一点。A = A; 这一点。B = B; } Test.prototype.f =函数(c) { 返回。A +这个。B + c; }; var test = new test (5,10); console.log(测试); console.log (test.f (3));
继承
在JavaScript中进行继承的一个简单而有效的方法是使用以下两行代码:
B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;
这类似于这样做:
B.prototype = new A();
两者之间的主要区别是,A的构造函数在使用Object时不运行。创建,这更直观,更类似于基于类的继承。
你总是可以选择在创建B的新实例时运行A的构造函数,方法是将它添加到B的构造函数中:
function B(arg1, arg2) {
A(arg1, arg2); // This is optional
}
如果你想将B的所有参数传递给A,你也可以使用Function.prototype.apply():
function B() {
A.apply(this, arguments); // This is optional
}
如果你想在B的构造函数链中混合另一个对象,你可以combine object。用Object创建。分配:
B.prototype = Object.assign(Object.create(A.prototype), mixin.prototype);
B.prototype.constructor = B;
Demo
function A(name) { this.name = name; } A.prototype = Object.create(Object.prototype); A.prototype.constructor = A; function B() { A.apply(this, arguments); this.street = "Downing Street 10"; } B.prototype = Object.create(A.prototype); B.prototype.constructor = B; function mixin() { } mixin.prototype = Object.create(Object.prototype); mixin.prototype.constructor = mixin; mixin.prototype.getProperties = function() { return { name: this.name, address: this.street, year: this.year }; }; function C() { B.apply(this, arguments); this.year = "2018" } C.prototype = Object.assign(Object.create(B.prototype), mixin.prototype); C.prototype.constructor = C; var instance = new C("Frank"); console.log(instance); console.log(instance.getProperties());
Note
对象。create可以在包括IE9+在内的所有现代浏览器中安全使用。对象。assign不能在任何版本的IE和一些移动浏览器中工作。建议对对象进行填充。创建和/或对象。如果您希望使用它们并支持未实现它们的浏览器,则分配。
你可以为Object找到一个polyfill。建立在这里 还有一个是Object。分配。