函数

时间:2016-07-07 19:19:45

标签: javascript function scope

我有SCOPE问题。当我在函数外面声明“var text”时,一切正常。但是在函数内部它只在第一部分起作用。这就是我的意思:

这是一个缓冲功能。执行缓冲区(“任何东西”)保存“任何东西”。执行buffer() - 没有属性将返回所有属性。

  • 缓冲液( “AL”)
  • 缓冲液( “前”)
  • buffer()< =应该返回Alex

但是“text”的SCOPE是错误的,它不会返回保存的属性。

  function makeBuffer() {
    var text = "";
    if (arguments.length != 0) {
      for (let i = 0; i < arguments.length; i++) {
        console.log(`Adding argument - (${arguments[i]})`);
        text += arguments[i];
        console.log(`New text - (${text})`);
      }
    } else {
      console.log(`text - (${text})`);
      return text;
    }
  }
  var buffer = makeBuffer;


  buffer("One", "Two");
  document.write(buffer());

4 个答案:

答案 0 :(得分:5)

这是正常行为。

当范围消失时,给定范围中定义的变量就会消失。每次调用函数都会创建一个新的范围。

在函数外声明变量是在调用之间共享值的标准方法。

答案 1 :(得分:3)

你想要的是工厂:

function makeBuffer() {
  var text = "";
  
  return function buffer() {
    if (arguments.length != 0) {
      for (let i = 0; i < arguments.length; i++) {
        console.log(`Adding argument - (${arguments[i]})`);
        text += arguments[i];
        console.log(`New text - (${text})`);
      }
    } else {
      console.log(`text - (${text})`);
      return text;
    }
  }
}

var buffer = makeBuffer();

buffer("One", "Two");
document.write(buffer());

答案 2 :(得分:1)

您可以使用对象执行此操作。这将使您的代码更有条理。

&#13;
&#13;
var Buffer = function() {
  this.text = "";
}
Buffer.prototype.append = function() {
  for (var i = 0; i < arguments.length; i++) {
    this.text += arguments[i];
  }
}
Buffer.prototype.get = function() {
  return this.text;
}

var buffer = new Buffer();
buffer.append("One", "Two");
document.write(buffer.get());
&#13;
&#13;
&#13;

使用ES6语法更加甜蜜:

&#13;
&#13;
class Buffer {
  constructor() {
    this.text = "";
  }
  append() {
    this.text = this.text.concat(...arguments);
  }
  get() {
    return this.text;
  }
}

var buffer = new Buffer();
buffer.append("One", "Two");
document.write(buffer.get());
&#13;
&#13;
&#13;

答案 3 :(得分:1)

正如昆汀在答案中正确指出的那样,这是一种正常行为。

将值保留在函数而不将变量声明为外部的另一种选择是作为属性添加到函数本身。

在JavaScript中,函数是第一类对象,您可以将这些数据直接放入函数对象中(就像在任何其他对象中一样)。

下面的示例,请注意如何从您的函数text)获取属性buffer.text

&#13;
&#13;
function makeBuffer() {
  makeBuffer.text = "";
  if (arguments.length != 0) {
    for (let i = 0; i < arguments.length; i++) {
      console.log(`Adding argument - (${arguments[i]})`);
      makeBuffer.text += arguments[i];
      console.log(`New text - (${makeBuffer.text})`);
    }
  } else {
    console.log(`text - (${makeBuffer.text})`);
    return makeBuffer.text;
  }
}

var buffer = makeBuffer;

buffer("Al", "ex");
console.log(`buffer.text - (${buffer.text})`);
&#13;
&#13;
&#13;

或者考虑使用闭包来保持函数调用之间的文本值。

  

闭包是指独立(自由)变量的函数   (在本地使用但在封闭范围内定义的变量)。   换句话说,这些功能记得&#39;其中的环境   他们被创造了。 More info here

&#13;
&#13;
let makeBuffer = function() {
  // closure
  let text = "";
  return function() {
    if (arguments.length != 0) {
      for (let i = 0; i < arguments.length; i++) {
        console.log(`Adding argument - (${arguments[i]})`);
        text += arguments[i];
        console.log(`New text - (${text})`);
      }
    } else {
      console.log(`text - (${text})`);
      return text;
    }
  }
};
var buffer = makeBuffer();
buffer("Al", "ex");
&#13;
&#13;
&#13;