繁体   English   中英

JavaScript中的var thing和function thing()有什么区别?

[英]What is the difference between var thing and function thing() in JavaScript?

我只是想知道以下JavaScript对象声明之间的区别。 具体来说,事物类中的事物对象文字和事物1对象之间的区别。

码:

var thing = {
    sanity:0,
    init:function(){
        //code
    },
    send:function(){
        //code
    }
}

function thing(){
    this.sanity = 0;
    this.init = function(){
        //code
    };
    this.send = function(){
        //code
    };
}

thing1 = new thing();

静态对象/对象文字

静态对象或对象文字不需要使用new运算符进行实例化,也可以像单例一样运行。 请考虑以下示例:

码:

var staticObject1 = {
 a: 123,
 b: 456
};
var staticObject2 = staticObject1;
console.log(staticObject1, staticObject2);
staticObject2.b = "hats";
console.log(staticObject1, staticObject2);

输出:

Object a=123 b=456  Object a=123 b=456
Object a=123 b=hats Object a=123 b=hats

请注意,更改staticObject2.b也会影响staticObject1.b 然而,这可能并不总是期望的效果。 许多库(如Dojo )提供了一种对象克隆方法,如果要复制静态对象,可以缓解这种情况。 继续前面的示例,请考虑以下事项:

码:

var staticObject3 = dojo.clone(staticObject1); // See the doc in the link above
staticObject1.a = "pants";
console.log(staticObject1, staticObject2, staticObject3);

输出:

Object a=pants b=hats Object a=pants b=hats Object a=123 b=hats

请注意, staticObject1staticObject2的成员的值是相同的,而staticObject3不受对这些其他对象的更改的影响。

静态对象对于创建项目或库命名空间也很有用,而不是填满全局范围,并提升兼容性,就像没有人的业务一样。

在创建需要可移植性或互操作性的库时,这非常有用。 这可以在流行的库中看到,例如Dojo,YUI和ExtJs,其中所有或大多数方法分别被称为dojo.examplMethod()YUI().exampleMethod() Ext.exampleMethod()Ext.exampleMethod()

静态对象也可以被认为与C / C ++中的struct类似。

类构造函数/实例化对象

JavaScript中的类基于原型继承,这是一个更复杂的主题,可以在这里这里这里阅读

与静态对象相反,由于JavaScript的closuer属性,这种对象创建方法为私有范围对象成员和方法提供了独特的机会。 请考虑以下私有类成员示例:

码:

var SomeObject = function() {
    var privateMember = "I am a private member";
    this.publicMember = "I am a public member";

    this.publicMethod = function() {
        console.log(privateMember, this.publicMember);
    };
};

var o = new SomeObject();
console.log(typeof o.privateMember, typeof o.publicMember);
o.publicMethod();

输出:

undefined string
I am a private member I am a public member

请注意, typeof o.privateMember是“未定义的”,不能在对象外部访问,但是来自内部。

也可以制作私有方法,但不是那么简单,但仍然很容易实现。 问题在于,值this私有方法默认的内部window和两种技术之一必须应用,以确保this指的是我们中工作,在这种情况下,对象实例SomeObject 请考虑以下示例:

码:

var SomeObject = function() {
    var privateMember = "I am a private member";
    var privateMethod = function() {
        console.log(this.publicMember);
    };

    this.publicMember = "I am a public member";
    this.publicMethod = function() {
        console.log(privateMember, this.publicMember);
    };
    this.privateMethodWrapper = function() {
        privateMethod.call(this);
    }
};

var o = new SomeObject();
console.log(typeof o.privateMethod, typeof o.publicMethod, typeof o.privateMethodWrapper);
o.privateMethodWrapper();

输出:

undefined function function
I am a public member

请注意,withing privateMethodWrapper() privatemethod使用执行call和传递this对函数的上下文。 这一切都很好; 但是,以下技术是优选的(在我看来),因为它简化了调用范围并产生相同的结果。 上一个示例可以更改为以下内容:

码:

var SomeObject = function() {
    var self          = this;
    var privateMember = "I am a private member";
    var privateMethod = function() {
        console.log(self.publicMember);
    };

    this.publicMember = "I am a public member";
    this.publicMethod = function() {
        console.log(privateMember, this.publicMember);
    };
    this.privateMethodWrapper = function() {
        privateMethod();
    }
};

var o = new SomeObject();
console.log(typeof o.privateMethod, typeof o.publicMethod, typeof o.privateMethodWrapper);
o.privateMethodWrapper();

输出:

undefined function function
I am a public member

这个答案是我博客上帖子的基础,我在这里给出了更多的例子。 希望有所帮助;)

案例2引用了javascript 类构造函数 一个明显的区别是变量还不是一个对象,所以你不能在内部引用thing1.sanity。 您必须在调用任何内部成员之前通过创建所述类的实例来初始化该类:

var myConstructor = function() {
    this.sanity = 0;
}

// wont work
alert(myConstructor.sanity);

// works
var thing1 = new myConstructor();
alert(thing1.sanity);

这篇文章比我的快速示例更深入:

类构造函数与对象文字

不同之处在于thing1对象与thing1类相关联,并且将继承(不是字面上) thing1原型。

例如,您可以稍后写

thing.prototype.initAndSend = function() { this.init(); this.send(); };

然后,您将能够编写thing1.initAndSend()而无需修改thing1 另外, thing1.constructor将等于thing方法,而{}.constructor等于Object

顺便说一句,标准惯例是大写类名。

使用第一种方法,您将声明一个对象。 对于第二个,您将声明一个类,您可以从中实例化(即创建)许多不同的副本。

函数是对象和构造函数(您可以使用new实例化它们)。

散列表/对象( {} )无法实例化,因此它们通常用作数据结构。 我不太确定将它们称为“物体”是否明智。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM