【问题标题】:the "new" word changes a function to an object?“新”字将功能更改为对象?
【发布时间】:2014-10-19 19:40:18
【问题描述】:

我遇到了一些问题,a 有这样的功能:

var sayHi = function(string){
  console.log(string + '' + this.name);
};

那我需要做:

sayHi = giveContext(sayHi,{"name":"moe"});

然后我做:

function giveContext(func,obj){

  var fn = func;
  fn.prototype.name = obj.name;

  var myFn = new fn;

  return myFn; 

}

预期的行为会是:

sayHi('Hello')  // ==> "Hello moe"

问题是 givecontext 中的“new”关键字返回一个对象而不是一个函数。 我只得到一个

undefined moe 
Uncaught TypeError: object is not a function 

我错过了什么?

【问题讨论】:

  • 你为什么要分配sayHi两次?
  • 对不起,我打错了,它不应该分配两次,已经编辑过

标签: javascript function object this


【解决方案1】:

当你使用new fn时,它会调用函数fn作为对象的构造函数,结果就是创建的对象。

基本上是这样的:

var myFn = new fn;

作为:

var myFn = {}; // create an object
fn.call(myFn); // call the constructor with the object as context

(当然还有更多事情要做,但这是目前最重要的事情。)

因此,函数giveContext 不会为函数提供上下文并返回它,而是将函数作为对象的构造函数调用并返回该对象。函数内部的代码已经被调用(这就是为什么有控制台输出的原因),当你尝试使用来自giveContext 的返回值作为函数时,你会得到一个错误,因为它根本不是一个函数.

已经有一个内置的method bind 为函数设置上下文:

sayHi = sayHi.bind({"name":"moe"});

(请注意该方法的支持信息,例如在 iE 8 中不支持。)

您也可以在不使用bind 方法的情况下通过创建一个调用该函数的函数来执行相同的操作:

function giveContext(f, obj) {
  return function(){
    return f.apply(obj, arguments);
  };
}

【讨论】:

  • 是的,但这是棘手的部分,本机方法“绑定”不能用于本练习
  • @flaalf:我添加了一个替代方案,没有使用上面的bind
  • 我忘了说,giveContext 函数在另一个脚本中,这会干扰 apply 方法吗?
  • @flaalf:我调整了代码以使用apply 以包含在发布评论后立即传递给函数的参数。检查您是否拥有当前版本。关于 giveContext 在另一个脚本中,一旦代码被加载和解析,它来自哪里都没有关系。
【解决方案2】:

是的,JavaScript 是面向对象的,所以当你说new fn 时,它会创建一个新对象。在您的设置中,您的函数有一个 name 属性,因此您应该使用 "Hello " + sayHi.name 来获得您期望的结果。

您会想要阅读这篇文章以获得一个很好的概述:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript

【讨论】:

  • 原来的sayHi函数不能改,我的意思是,这个练习的目的是把“name”变量插入到sayHi函数中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 2016-08-24
  • 1970-01-01
  • 2018-06-09
  • 1970-01-01
  • 2021-11-07
  • 2021-11-06
相关资源
最近更新 更多