使用新关键字调用JavaScript函数

huangapple go评论77阅读模式
英文:

javascript call function with new keyword

问题

    function outer(abc) {
      this.abc = abc;
      return function inner() {
        this.abc = abc;
        return this.abc;
      };
    }

在上面的代码中我无法像下面这样实例化外部函数

      var obj = new outer(123);
      console.log(obj.abc)
    //这里 obj.abc 变成了 undefined

但是在下面的代码中当删除外部函数的 return 关键字时它可以正常工作

    function outer(abc) {
          this.abc = abc;
           function inner() {
            this.abc = abc;
            return this.abc;
          }
        }
     var obj = new outer(123);
           console.log(obj.abc)


我还有一个疑问为什么我不能像下面这样创建返回的函数的对象

    function outer(abc) {
          this.abc = abc;
           return function inner() {
            this.abc = abc;
            return this.abc;
          }
        }
    var obj2= new outer(11)();
    console.log(obj2.abc)
英文:
function outer(abc) {
  this.abc = abc;
   return function inner() {
    this.abc = abc;
    return this.abc;
  }
}

In the above code I cannot intantiate outer function like below

  var obj = new outer(123);
   console.log(obj.abc)
//here obj.abc get undefined

but the below code works when removed the return keyword for outer function

function outer(abc) {
      this.abc = abc;
       function inner() {
        this.abc = abc;
        return this.abc;
      }
    }
 var obj = new outer(123);
       console.log(obj.abc)

I have one more concerned is that why cannot I create object of returned function like below?

function outer(abc) {
      this.abc = abc;
       return function inner() {
        this.abc = abc;
        return this.abc;
      }
    }
var obj2= new outer(11)();
console.log(obj2.abc)

答案1

得分: 1

如果您使用带有new的函数(从而创建一个对象实例),并从该函数返回一个值,该返回值将被用作new的结果,而不是该对象实例。当您返回一个函数并直接调用它而不绑定到上下文时,它的上下文将是浏览器中的window

> 如果构造函数返回一个非原始值,则此返回值将成为整个新表达式的结果。否则,如果构造函数没有返回任何内容或返回一个原始值,则将返回newInstance。 (通常构造函数不会返回值,但它们可以选择这样做以覆盖正常的对象创建过程。)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new

要修复您的代码,只需删除对this的依赖:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function outer(abc) {
  this.abc = abc;
   return function inner() {
    return abc;
  }
}

console.log((new outer(123))());

<!-- end snippet -->

无论如何,我认为你这里的模式并不合理。看起来你想实现一种更清晰和更简单的模式。而且更具体地说,@VLAZ指出外部类中的this.abc = abc;是没有意义的,因为后面没有使用它,我也注意到了,但为了集中注意力而避免了它。好吧,作为JS学习的一部分...

> @silentmantra 请再澄清下面的代码疑惑,我一定会接受你的回答。为什么我不能创建内部函数的对象,它什么都不返回。函数外部(abc) { this.abc = abc; return function inner() { this.abc = abc; } } var result = new outer(23)(); console.dir(result);

如上所述和显示,当您调用返回的函数时,您失去了this上下文,它变为window(默认上下文)。所以基本上返回了window.abs,它是11,因为您已经对它赋值了。
而且您最后的console.log(obj2.abc)没有意义,因为您试图获取一个数字的属性:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function outer(abc) {
      this.abc = abc;
       return function inner() {
        this.abc = abc;       
        return this.abc;
      }
    }

var obj2= new outer(11)();

console.log(obj2)

console.log(obj2.abc) // 11 doesn't have 'abs' property

console.log(window.abc) // oops, but window has

<!-- end snippet -->

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

英文:

If you use a function with new (thus creating an object instance) and return from this function the returned value will be used as result of new instead of this object instance. When you return a function and call it directly without binding to a context its context would be window in a browser:

> If the constructor function returns a non-primitive, this return value becomes the result of the whole new expression. Otherwise, if the constructor function doesn't return anything or returns a primitive, newInstance is returned instead. (Normally constructors don't return a value, but they can choose to do so to override the normal object creation process.)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function outer(abc) {
  this.abc = abc;
   return function inner() {
    console.log(this);
    this.abc = abc;
    return this.abc;
  }
}

console.log((new outer)());

<!-- end snippet -->

To fix your code just remove dependence on this:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function outer(abc) {
  this.abc = abc;
   return function inner() {
    return abc;
  }
}

console.log((new outer(123))());

<!-- end snippet -->

Anyway I think your pattern here doesn't make much sense. Seems you want to achieve a pattern that would be done much cleaner and easier.
And to be more specific @VLAZ has pointed that this.abc = abc; in the outer class is pointless since not used later, that I noticed also but avoided to gain some focus on it. Ok as a part of JS learning though...

> @silentmantra Please clear one more doubt of below code, I will surely accept your answer. why I cant create object of inner function where it returns nothing. function outer(abc) { this.abc = abc; return function inner() { this.abc = abc; } } var result = new outer(23)(); console.dir(result);

As mentioned and shown above when you call the returned function you lose your this context and it becomes window (default one). So basically window.abs returned and it's 11 since you have assigned to it.
and your final console.log(obj2.abc) doesn't make sense since you try to get a prop of a number:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function outer(abc) {
      this.abc = abc;
       return function inner() {
        this.abc = abc;       
        return this.abc;
      }
    }

var obj2= new outer(11)();

console.log(obj2)

console.log(obj2.abc) // 11 doesn&#39;t have &#39;abs&#39; property

console.log(window.abc) // oops, but window has

<!-- end snippet -->

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

huangapple
  • 本文由 发表于 2023年5月29日 19:37:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76357005.html