JavaScript语法:什么是({})它是函数还是对象?

时间:2014-01-26 00:03:50

标签: javascript oop object backbone.js

作为具有OOP背景的开发人员(c#,Java)OOP JavaScript对我来说是个疯子。我正在努力学习语言的基础,然后跳上图书馆(我错了吗?);

所以,我检查了十几本关于对象,函数等的书籍/教程。了解了几种创建对象的方法,但几乎每个JS库中使用的语法都让我困惑。即

var Person = Backbone.extend.Model({
 //pretty complex staff
 })

什么是幕后模特?宾语?功能

3 个答案:

答案 0 :(得分:13)

这不是正确的主干语法。那应该是:

Backbone.Model.extend({

});

在这种情况下,extend是一个函数。请注意,您使用()调用它。但是,javascript中的函数也是对象(稍后会详细介绍)。您可能会对其中的{}感到困惑。那是因为您将该对象作为参数传递给函数。

如果extend是一个期望字符串作为参数/参数的函数,它将如下所示:extend('some string')。在这种情况下,它是一个对象。例如:

var someObject = {
  someProperty: 'someValue'
}
var Person = Backbone.Model.extend(someObject);

与:

相同
var Person = Backbone.Model.extend({
  someProperty: 'someValue'
});

以下是函数中可能出现的示例:

Backbone.Model.extend = function(obj) {
  console.log(obj.someProperty); //logs "someValue"
}

正如我所说,在javascript中,函数也是对象。实际上,大多数东西都是物体。我建议你研究一下这个。由于这不是你问题的焦点,我只是简单地说明一下:

var someObj = {
  someProperty: '123'
};
console.log(someObj.someProperty); //logs "123"

var someFunction = function() {

};
someFunction.someProperty = '123';
console.log(someFunction.someProperty); //logs "123"

尽管如此,最好添加到原型中,以便继承可以这样工作:

someFunction.prototype.someProperty = '123';
var foo = new someFunction();
console.log(foo.someProperty); //logs "123"

<强> Here's a little demo you can mess with (click).

所以..总之,JavaScript是赢家。

答案 1 :(得分:2)

你确定你输入的是正确的吗?我认为你颠倒了Modelextend的顺序。我现在正在查看文档,我看到了:

  

模型是任何JavaScript应用程序的核心,包含交互式数据以及围绕它的大部分逻辑:转换,验证,计算属性和访问控制。您使用特定于域的方法扩展Backbone.Model,而Model提供了一组用于管理更改的基本功能。

extend函数在许多Javascript库中实现:Backbone,Underscore和jQuery等。它的作用是获取一个对象并向其中添加方法和实例变量。毕竟在Javascript中,对象只是哈希。这会创建一个具有一些方法和数据的对象。

var counter = {};
counter.count = 0;
counter.increment = function() {
    this.count++;
}
counter.decrement = function() {
    this.count--;
}

如果要继承,可以使用对象或其构造函数的prototype属性。 extend方法是一种模拟方法。以下是Backbone文档的更多内容:

  

extendBackbone.Model.extend(properties,[classProperties])

     

要创建自己的Model类,可以扩展Backbone.Model并提供实例属性,以及可选的classProperties直接附加到构造函数。

     

extend正确设置原型链,因此使用extend创建的子类可以根据需要进一步扩展和子类化。

var Note = Backbone.Model.extend({

    initialize: function() { ... },

    author: function() { ... },

    coordinates: function() { ... },

    allowedToEdit: function(account) {
        return true;
    }

});

在传统的Javascript中,你会写:

function Note() {
    this.initialize  = function() {...};
    this.author      = function() {...};
    this.coordinates = function() {...};
    this.allowedToEdit = function(account) {
        return true;
    };
}

Note.prototype = new Model();  // Inheritance.

JavaScript中的继承让我想起了Perl格言:有不止一种方法可以做到这一点。

答案 2 :(得分:1)

欢迎使用stackoverflow,

我强烈建议你看一下Douglas Crockford's Website,还有洞察力videos in YUI Theater - 从道格拉斯开始。他是发现JavaScript has good parts的人。我还发现John Resig's Secrets of the JavaScript Ninja非常有助于克制语言(约翰是无所不在的jQuery Library的创造者)。我会进一步建议你看一些库(及其代码 - 我是如何学习它的 - 只需从jQuery开始)。那里有a ton of other libraries,但一次只有一步: - )。

现在问你的问题: Backbone.Model是一个构造函数,通常你会像在Java new Backbone.Model({ configOption: true, ... })中一样使用它。但是多汁的JavaScript可以让你在引擎盖下做疯狂的事情。例如,您可以实现自己的OOP类实现,也可以像在Scheme或Lisp中那样以函数式编程。你在这里看到的是Backbone自己的子类型包装器(几乎任何体面的JS库提供了一些方法来实现这一点)。 代码实际上正在做一些事情:

// Creating a sub type of the Backbone.Model *class* - it's not really 
// a class like in Java or C# but rather a (constructor) function.
var Person = Backbone.Model.extend({ 
    defaults: {
        hasTheOneRing: true
    },
    initialize: function (hasTheOneRing) {
        // Note that Backbone is implementing getters/setters
        // under the hood so you can listen for change events later
        this.set('hasTheOneRing', hasTheOneRing);
    }
    // More configuration ...
});

// Person now is a constructor function that creates instances
// of it's *class* when you create an object with it
var frodo = new Person(true),
    sam = new Person(); // Note that you can supply as many arguments as you wish

// Frodo has the ring
console.log(frodo.get('hasTheOneRing')); 

// Sam doesn't have the ring (well not all the time)
console.log(sam.get('hasTheOneRing')); 

// In plain old JavaScript the sub typing mechanism works a little bit like this:

// A constructor function is just a function
function Person() {
    // JS doesn't have the notion of *super* or *base* but you
    // can emulate the behavior as many libraries do in the wild
    Backbone.Model.call(this);
}

// The prototype of a person is based on that of a Backbone.Model
Person.prototype = Object.create(Backbone.Model.prototype);

// Object.create has not been there since the beginning. After
// Douglas Crockford discovered the good parts this function
// has been adapted into the standard portfolio of every modern browser
// what it does is essentially just:
function create(object) {
    // There's actually more going on in here but you get the idea
    function F() {}
    F.prototype = object;
    return new F();
}

// So this means almost the same
Person.prototype = new Backbone.Model();

我喜欢JS的方式是阅读库代码 - 而Backbone is open source因此阅读并被令人敬畏的 g 感到惊讶。我认为,JS只是通过网络发送的纯文本,对语言在生态系统中变得强大有很大的影响,即使微软也无法阻止它。

尝试使用该语言,当它点击您时,很可能真的开始喜欢它: - )。

快乐的编码!