Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/429.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用函数初始化带有和不带return语句的JavaScript对象有什么区别?_Javascript - Fatal编程技术网

使用函数初始化带有和不带return语句的JavaScript对象有什么区别?

使用函数初始化带有和不带return语句的JavaScript对象有什么区别?,javascript,Javascript,我有两个初始化对象的函数。init和differentinitit function init(){ return {a:5}; } function differentInit(){ this.a =5; } obj = init(); newobj = new differentInit() 对象obj和newobj有何不同? 这是JavaScript解释器显示为两个对象内容的内容 >obj <·Object {a: 5} >newobj <·d

我有两个初始化对象的函数。init和differentinitit

function init(){
    return {a:5};
}

function differentInit(){
    this.a =5;
}

obj = init();
newobj = new differentInit()
对象obj和newobj有何不同?
这是JavaScript解释器显示为两个对象内容的内容

>obj
<·Object {a: 5}
>newobj
<·differentInit {a: 5}
>obj
纽奥布
对象obj和newobj有何不同

考虑到您所展示的函数,唯一真正的区别是第二个函数与
对象.prototype
之间有一个额外的原型(具有不同的
构造函数
属性)。第一个直接继承自
对象。prototype

例如,
obj

+----------+ Object.prototype-------------+--->| toString | | | valueOf | | | ... | | +----------+ +---------------+ | obj---->| [[Prototype]] |----+ | a: 5 | +---------------+ +----------+ Object.prototype--------------------------------------+--->| toString | | | valueOf | | | ... | | +----------+ +---------------+ | differentInit.prototype------+--->| [[Prototype]] |---+ | +---------------+ | | +---------------+ | newObj->| [[Prototype]] |----+ | a: 5 | +---------------+ (注意,
Object.prototype
differentInit.prototype
指向的对象都有一个
constructor
属性,分别指向
Object
differentinitit
。因此
obj.constructor
将是
Object
newObj.constructor
将是
Differentinitit
。我本来会将其添加到图表中,但这会使它们变得不必要的复杂…)

除非您在differentInit.prototype中添加了一些内容,否则它不会产生任何显著的实际差异


既然您已经标记了您的问题
json
,我只想指出,在您的问题中没有使用任何json。json是用于数据交换的文本符号。如果您处理的是程序源代码,而不是字符串,那么您就没有处理json


我一直认为只有使用
object.create()
方法才能使用原型创建对象

在JavaScript中,所有对象都有原型,除非它们是用
Object.create(null)
创建的(这使它们在
[[Prototype]]
内部槽中有
null
,例如,它们没有原型)

…还有多少其他方法可以使用原型创建对象

可以通过以下方式创建具有原型的对象:

  • 使用对象初始值设定项,例如
    obj={}
    ,它使用
    object.prototype
    作为其原型来创建它

  • 通过对函数使用
    new
    操作符,函数的
    prototype
    属性所引用的对象将被指定为
    new
    创建的对象的原型。使用
    函数创建的所有函数(或
    )关键字获取一个
    prototype
    属性,该属性上有一个空白对象;然后可以添加或替换该属性。(如果函数的
    prototype
    null
    new
    使用
    对象。prototype

    请注意,与
    new
    一起使用的函数可以是使用
    function
    关键字定义的任何函数:

    // Using `function`
    function Foo() {
    }
    Foo.prototype.bar = function() {
        console.log("Foo instance says 'bar'!");
    };
    var f = new Foo();
    f.bar();
    
    class Foo {
        bar() {
            console.log("Foo instance says 'bar'!");
        }
    }
    var f = new Foo();
    f.bar();
    
    或者从ES2015开始,使用
    类定义的函数
    关键字:

    // Using `function`
    function Foo() {
    }
    Foo.prototype.bar = function() {
        console.log("Foo instance says 'bar'!");
    };
    var f = new Foo();
    f.bar();
    
    class Foo {
        bar() {
            console.log("Foo instance says 'bar'!");
        }
    }
    var f = new Foo();
    f.bar();
    
    除了几个小细节,上面的两个代码片段做了相同的事情:它们定义了一个名为
    Foo
    的函数,您希望通过
    new
    调用该函数,该函数上有
    Foo.prototype
    bar

  • 使用
    Object.create(p)
    ,其中
    p
    被指定为结果对象的原型。与上面的#2不同,
    p
    可以
    null
    来创建一个没有原型的对象。这是在ES5中添加的,尽管它可以填充(除了
    null
    位)。(有一个可选的第二个参数不能填充。)

  • 创建对象后,可以通过两种方式设置对象的原型:

  • 使用ES2015中新增的或非常类似的。(它们之间唯一的区别是
    Reflect.setPrototypeOf
    将抛出一个非对象作为
    target
    object.setPrototypeOf
    将只返回您在这种情况下未更改的内容。这一点,一些JavaScript引擎还没有
    Reflect
    对象,但很快就会有了。)

  • (仅限向后兼容)使用,前提是对象(直接或间接)继承自
    对象。prototype
    注意:

    A.这仅适用于web浏览器中的JavaScript引擎

    B.在ES2015之前,它不是规范的一部分

    C.由于它在ES2015之前不在规范中,仅在web浏览器上定义,并且如果对象不是从
    对象.prototype
    继承,则将失败,在非常罕见的情况下,您需要在创建对象的原型后动态设置其原型,请改用
    Reflect.setPrototypeOf

  • 这个问题中使用的方法可以被认为是一种创建原型对象的好方法吗


    如果你所说的“方法”是指
    new differentinitit
    ,是的,这是创建具有特定原型的对象的一种完全正常的方式。通常你在创建多个对象时使用这种形式(一般意义上的对象“类”;例如,具有大多数共同特征的对象)。使用
    对象也是完全正常的。为该用例创建
    (有些人根本不喜欢使用
    新的
    操作符)。如果您只是一次性地希望一个特定对象从另一个特定对象继承,那么创建对象就是一个好办法。

    最实际的区别是

    obj.constructor==对象
    newobj.constructor===differentinitit
    
    Object.getPrototypeOf(obj)==Object.prototype;
    Object.getPrototypeOf(newobj)==differentinitit.prototype;
    
    obj实例of differentinitit===false
    differentInit的newobj实例===true
    

    否则(除非您修改
    differentinitit.prototype
    ),它们基本相同。

    为什么您只回答那些难以理解并提供解决方案的问题?@RayonDabre::-)