Heim  >  Fragen und Antworten  >  Hauptteil

javascript - JS 使用“构造函数”和“内置对象(Object)”创建对象有什么区别?

var myArr = Object();
myArr.name = "javascript";
myArr.age = 2017;
console.log(myArr);//Object {name: "javascript", age: 2017}
console.log(typeof myArr);//object
console.log(myArr.name);//javascript

function Fun(){}

var a = new Fun();
a.name = "javascript";//去掉new后,Cannot set property 'name' of undefined
a.age = 2017;//去掉new后,Cannot set property 'age' of undefined
console.log(a);//Fun {name: "javascript", age: 2017}
console.log(typeof a);//object
console.log(a.name);//javascript

上面代码中,使用“内置对象Object”创建对象,可以不使用new,Array也可以不使用new。

但是使用构造函数创建对象的话,如果不使用new就只是一个函数的返回值,也无法创建属性。

在我的理解,他们都是对象,为什么创建的时候就有区别了呢?

这是不是因为“Object”本来就是对象,而构造函数是通过函数封装的对象的原因呢?

我也不知道为什么我会有好多千奇百怪的问题。。。

PHP中文网PHP中文网2749 Tage vor1095

Antworte allen(7)Ich werde antworten

  • ringa_lee

    ringa_lee2017-04-11 12:40:58

    Object 里面有判断有没有写 new 的代码。如果没写就返回 return new Object()。在你的 Fun 里面也可以添加。比如:

    也可以

    function _Fun_() {}
    
    function Fun(){
     // 这样 new Fun() 和 Fun() 就没有区别了。
      return new _Fun_();
    }

    详见
    http://zonxin.github.io/post/...

    Antwort
    0
  • 天蓬老师

    天蓬老师2017-04-11 12:40:58

    不是很理解你的问题。。我说几点,希望对你有帮助~

    • ObjectFun一样是一个函数,他们本质上是Object类型的

    • 直接调用 a = Fun(),称之为一般函数调用,而你的Func函数体内没有返回结果,所以a=undefined,当然你不能给一个undefined创建属性。

    • 通过a = new Fun()调用,称之为构造函数调用。当通过new调用一个函数时发生了这几件事。
      a = new Fun()为例

      1. 构造一个空对象,假设命名为 obj = {},绑定obj__prot__Fun.prototype(涉及到js的原型链继承)

      2. 绑定函数执行环境中的this到刚才创建的空对象(即obj)上 (希望你理解了js中的this...)

      3. 执行Func函数体

      4. 如果函数体返回值是undefinednull或者不是Object类型,则返回值为最开始的obj
        所以var a = new Fun()a的值为空对象{}

    • a.name = "javascript";会直接在a上添加属性name="javascript"(这句话深究起来其实不简单..,懒得展开了,题主有兴趣多看书把。)

    使用“内置对象Object”创建对象,可以不使用new,Array也可以不使用new。

    最后ObjectArray可不使用new,因为他们内部做了判断,如果不是构造函数调用自动添加new.

    Antwort
    0
  • 巴扎黑

    巴扎黑2017-04-11 12:40:58

    是都可以创建对象,但是new 方法创建的对象的原型是 Fun ,即a.__proto__ = Fun.protoType;而第一种是myArr.__proto__ = Object.protoType
    看了一下题,发现回答有所偏差,其实可以在Fun中添加以下代码,实现安全的构造函数,达到不使用new也可创建函数:

    function Fun(){
        if(!this instanceof Fun){
            return new Fun();
        }
    }

    Antwort
    0
  • ringa_lee

    ringa_lee2017-04-11 12:40:58

    var a=Fun()表示a为函数Fun()的返回值,你Fun(){}没有返回值,a就是undefined

    你试试var a = Fun(){return new Object()}呗

    Antwort
    0
  • ringa_lee

    ringa_lee2017-04-11 12:40:58

    我怎么记得,不用new的,那是工厂模式。

    说白了就是以这个函数的返回值作为新的对象,如果你想这个函数加不加new都一样构造新的对象的话,那不想作为构造函数的其他函数怎么用呢。

    
        function add(a,b){
            this.sombra='boo';
            return a+b;
        }
        
        var c=add(1,2);//3
        var d= new add();//{sombra:'boo'}
    

    Antwort
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-11 12:40:58

    其实你要是把:

    var myArr = Object();

    换成

    var myArr = new Object();

    你不会觉得这么奇怪了,二者是相等的,只不过当你不以构造函数形式调用 Object 时,Object 等同于 new Object()(注:Array也是一样)

    但这样讲反而会更迷惑,为什么呢?原因在于原型树。可这样的话,头这一定会更头大;要不就说一说为什么需要 new

    我用你的示例进行思维拓展,假设你是在创建一个用户对象:

    var myArr = Object();
    myArr.name = "javascript";
    myArr.age = 2017;

    一个实例代表着一个人的姓名和年龄;我在这个基础增加了一个动作,即:zodiac() 方法来计算生肖。

    那好,假如我现在需要10个用户信息,那么我需要这样:

    var users = [];
    for (var i = 0; i < 10; i++) {
        var myArr = new Object();
        myArr.name = "javascript";
        myArr.age = 2017;
        myArr.zodiac = function() { return this.age === 1 ? '属龙' : '属鼠'; }
        users.push(myArr);
    }

    看似很简单,但首先每个实例都带有 zodiac() 方法是不是太浪费内存了?每一个计算生肖的是依赖时年龄,也没有必要每一次都创建。

    那好,我们可以改进一下,来解决这两个疑问。

    function User() { }
    
    // 用户生肖
    function UserZodiac() {
        this.zodiac = function() {
            return this.age === 1 ? '属龙' : '属鼠';
        }
    }
    
    // 将用户的原型绑定到用户生肖
    var userZodiac = new UserZodiac();
    User.prototype = userZodiac;
    
    var users = [];
    for (var i = 0; i < 10; i++) {
        var myArr = new User();
        myArr.name = "javascript";
        myArr.age = 2017;
        users.push(myArr);
    }

    当我们创建10个用户时,只需要实例一次 UserZodiac

    这才是 new 的魅力。

    其实当你调用一个函数时,newnew 没有什么区别,更有一些人提倡放弃 this (相当于放弃new)。

    老是有人拿原型树来考核一个人是否真懂JavaScript其实挺不合理。

    Antwort
    0
  • 阿神

    阿神2017-04-11 12:40:58

    Array Es文档
    Object Es文档

    Antwort
    0
  • StornierenAntwort