我想知道创建具有属性和方法的JavaScript对象的最佳方法是什么。

我见过有人用var self = this然后用self的例子。在所有函数中确保作用域总是正确的。

然后我看到了使用.prototype来添加属性的例子,而其他人则是内联的。

谁能给我一个适当的例子,一个JavaScript对象的一些属性和方法?


当前回答

你也可以试试这个

    function Person(obj) {
    'use strict';
    if (typeof obj === "undefined") {
        this.name = "Bob";
        this.age = 32;
        this.company = "Facebook";
    } else {
        this.name = obj.name;
        this.age = obj.age;
        this.company = obj.company;
    }

}

Person.prototype.print = function () {
    'use strict';
    console.log("Name: " + this.name + " Age : " + this.age + " Company : " + this.company);
};

var p1 = new Person({name: "Alex", age: 23, company: "Google"});
p1.print();

其他回答

当一个人在构造函数调用期间使用关闭“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的文章,您可能会学到很多东西。约翰·瑞西格也很出色。好运!

Douglas Crockford在《The Good Parts》中广泛讨论了这个话题。他建议避免使用new操作符来创建新对象。相反,他建议创建定制的构造函数。例如:

var mammal = function (spec) {     
   var that = {}; 
   that.get_name = function (  ) { 
      return spec.name; 
   }; 
   that.says = function (  ) { 
      return spec.saying || ''; 
   }; 
   return that; 
}; 

var myMammal = mammal({name: 'Herb'});

在Javascript中,函数是一个对象,可以用来与new操作符一起构造对象。按照惯例,打算用作构造函数的函数以大写字母开头。你经常会看到这样的事情:

function Person() {
   this.name = "John";
   return this;
}

var person = new Person();
alert("name: " + person.name);**

如果在实例化新对象时忘记使用new操作符,则得到的是一个普通的函数调用,并且它绑定到全局对象,而不是绑定到新对象。

创建对象

在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。分配。

继续鲍恩斯的回答

在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);

你也可以这样做,使用结构:

function createCounter () {
    var count = 0;

    return {
        increaseBy: function(nb) {
            count += nb;
        },
        reset: function {
            count = 0;
        }
    }
}

然后:

var counter1 = createCounter();
counter1.increaseBy(4);