函数的局部变量没有得到参数值

时间:2015-03-27 04:05:35

标签: javascript function scope arguments var

这对我来说很奇怪。我有

var j = "x";
var k = "y";

function fun1 ( a, b) {
  var j = a;
  var k = b;
  console.log("this.j is:", this.j);
  console.log("this.k is:", this.k);
  this.j = a;
  this.k = b;
  return this.j + this.k;
};

console.log("j is ", j);
console.log("k is ", k);
console.log("fun1(3,4) is ", fun1(3,4));
console.log("j is ", j);
console.log("k is ", k);
console.log("fun1(2,7) is ", fun1(2,7));
console.log("j is ", j);
console.log("k is ", k);

当我在Node.js中运行它时,我得到:

j is  x
k is  y
this.j is: undefined
this.k is: undefined
fun1(3,4) is  7
j is  x
k is  y
this.j is: 3
this.k is: 4
fun1(2,7) is  9
j is  x
k is  y

为什么声明时j和k不被设置为函数中的参数a和b?我不得不做两件事var j = a; AND this.j = a; !我做错了什么?

在节点中,输出正确显示全局中的j和k变量未被fun1中的局部变量j和k破坏。当我在Chrome或Firefox中运行时,全局变量DO GET被破坏了。换句话说,我得到

j is  x
k is  y
this.j is: undefined
this.k is: undefined
fun1(3,4) is  7
j is  3
k is  4
this.j is: 3
this.k is: 4
fun1(2,7) is  9
j is  2
k is  7

为什么本地范围不能保护全局var?

感谢任何提示。

1 个答案:

答案 0 :(得分:0)

我建议你去看看! :)这解释了如何使用这个,这是什么! Read here! Mozilla Developper Network

如果链接已死,这是文章。 (对不起,格式化并不完美,文字很长。)

  

概要   一个函数这个关键字在JavaScript中的表现略有不同   与其他语言相比。它之间也有一些差异   严格模式和非严格模式。

     

在大多数情况下,其值取决于函数的大小   调用。它不能在执行期间通过赋值来设置,它可能是   每次调用函数时都不同。 ES5引入了绑定   无论如何设置函数值的方法都是如此   调用。

     

语法此全局上下文在全局执行上下文中(在...之外)   任何函数),这是指全局对象,无论是严格的   模式与否。

     

console.log(this.document === document); // true

     

//在Web浏览器中,window对象也是全局对象:   console.log(这个===窗口); // true

     

this.a = 37;的console.log(window.a); // 37函数上下文   函数,其值取决于函数的调用方式。

     

简单的电话

function f1(){   return this; }

f1() === window; // global object In this case, the value of this is
     

未通过通话设置。由于代码不是严格模式,因此值   其中必须始终是一个对象,因此它默认为全局对象。

     

function f2(){" use strict&#34 ;; //见严格模式返回此; }

f2() === undefined; 
     

在严格模式下,其值保持为   进入执行上下文时设置的内容。如果不是   定义,它仍然未定义。它也可以设置为任何值,例如   as null或42或"我不是这个"。

     

注意:在第二个例子中,这应该是未定义的,因为f2是   在没有提供任何基础的情况下调用(例如window.f2())。此功能   当他们第一次开始支持时,在某些浏览器中没有实现   严格模式。结果,他们错误地返回了窗口对象。   作为对象方法

     

当一个函数作为一个对象的方法被调用时,它被设置为   调用该方法的对象。

     

在以下示例中,在函数内部调用o.f()时   这与o对象绑定。

var o = {   prop: 37,   f: function() {
    return this.prop;   } };

console.log(o.f()); // logs 37 Note that this behavior is not at all
     

受功能定义的方式或位置的影响。在以前   例如,我们将函数内联定义为f成员   o的定义。但是,我们可以很容易地定义   首先将函数附加到o.f.这样做会导致   相同的行为:

var o = {prop: 37};

 function independent() {   return this.prop; }

o.f = independent;

console.log(o.f()); // logs 37 This demonstrates that it matters only
     

该函数是从o。

的f成员调用的      

同样,此绑定仅受最直接的影响   会员参考。在下面的例子中,当我们调用时   函数,我们将其称为对象o.b的方法g。这段时间   执行,这个函数内部将引用o.b.这个事实   对象本身就是o的成员,没有任何后果;最多   立即参考是最重要的。

o.b = {g: independent, prop: 42}; console.log(o.b.g()); // logs 42
this on the object's prototype chain
     

对于在某处定义的方法,同样的概念也适用   对象的原型链。如果方法是在对象的原型上   链,这是指调用方法的对象,就好像是   方法就在对象上。

var o = {f:function(){ return this.a + this.b; }}; var p =
Object.create(o); p.a = 1; p.b = 4;

console.log(p.f()); // 5 In this example, the object assigned to the
     

变量p没有自己的f属性,它从它继承它   原型。但最终查找f并不重要   在o上找到具有该名称的成员;查找开始作为参考   p.f,所以这个函数内部获取对象的值   称为p。也就是说,因为f被称为p的方法,所以它   这指的是p。这是JavaScript的一个有趣特性   原型继承。

     

这是使用getter或setter

     

同样,当从a调用函数时,同样的概念也成立   吸气剂或二传手。用作getter或setter的函数就是这个   绑定到设置或获取属性的对象。

function modulus(){   return Math.sqrt(this.re * this.re + this.im *
this.im); }

var o = {   re: 1,   im: -1,   get phase(){
    return Math.atan2(this.im, this.re);   } };

Object.defineProperty(o, 'modulus', {
    get: modulus, enumerable:true, configurable:true});

console.log(o.phase, o.modulus); // logs -0.78 1.4142 As a constructor
     

当一个函数用作构造函数(使用new关键字)时,它就是   这与被构造的新对象绑定。

     

注意:虽然构造函数的默认值是返回对象   由此引用,它可以返回一些其他对象(如果   返回值不是一个对象,然后返回该对象。

     

/ * *构造函数的工作方式如下:* * function MyConstructor(){*   //实际的函数体代码在这里。 * //创建属性   |它as * //通过分配给他们。例如,* this.fum =   " NOM&#34 ;; * //等等...... * * //如果函数有返回   声明* //返回一个对象,该对象将是*
  // | new |的结果表达。否则,* //结果   表达式是当前绑定到| this |的对象* // * //   (即最常见的常见情况)。 *} * /

function C(){   this.a = 37; }

var o = new C(); console.log(o.a); // logs 37


function C2(){   this.a = 37;   return {a:38}; }

o = new C2(); console.log(o.a); // logs 38 In the last example (C2),
     

因为在构造期间返回了一个对象,即新对象   这必然会被丢弃。 (这基本上是这样的   声明" this.a = 37;"死代码。它并没有完全死亡,因为   它被执行,但它可以消除,没有外部影响。)

     

致电并申请

     

如果函数在其正文中使用this关键字,则其值可以是   使用call或apply绑定到调用中的特定对象   所有函数都从Function.prototype继承的方法。

function add(c, d){   return this.a + this.b + c + d; }

var o = {a:1, b:3};
     

//第一个参数是用作//'此',后续的对象   参数在函数调用中作为//参数传递   add.call(o,5,7); // 1 + 3 + 5 + 7 = 16

     

//第一个参数是用作//'这个',第二个参数   是一个数组,其//成员用作函数中的参数   调用add.apply(o,[10,20]); // 1 + 3 + 10 + 20 = 34请注意   调用并应用,如果传递的值不是对象,则为   将尝试使用内部将其转换为对象   ToObject操作。因此,如果传递的值是7或者原语   ' foo',它将使用相关的转换为Object   构造函数,因此原始数字7被转换为对象,就好像   通过新的数字(7)和字符串' foo'一个对象好像是新的   字符串(' foo'),例如

function bar() {   console.log(Object.prototype.toString.call(this));
}

bar.call(7); // [object Number] The bind method
     

ECMAScript 5引入了Function.prototype.bind。调用   f.bind(someObject)创建一个具有相同主体和范围的新函数   作为f,但在原始函数中出现的情况,在新的   函数它永久绑定到bind的第一个参数,   无论函数是如何使用的。

function f(){   return this.a; }

var g = f.bind({a:"azerty"}); console.log(g()); // azerty

var o = {a:37, f:f, g:g}; console.log(o.f(), o.g()); // 37, azerty As
     

DOM事件处理程序

     

当一个函数用作事件处理程序时,它的设置为   事件触发的元素(某些浏览器不遵循此规则)   使用除以外的方法动态添加的侦听器约定   的addEventListener)。

     

//当作为监听器调用时,将相关元素变为蓝色函数   bluify(e){//始终是真的console.log(这=== e.currentTarget);
  //当currentTarget和target是同一个对象时为true   console.log(这=== e.target); this.style.backgroundColor =   '#A5D9F3&#39 ;; }

// Get a list of every element in the document var elements =
document.getElementsByTagName('*');

// Add bluify as a click listener so when the // element is clicked
     

on,它变为蓝色(var i = 0; i   elements [i] .addEventListener(' click',bluify,false);在一个内联   事件处理程序

     

当从内联处理程序调用代码时,将其设置为   放置侦听器的DOM元素:

     

显示这个    以上警告显示按钮。但请注意,只有   外部代码以这种方式设置:

     

显示内心   在这种情况下,内部函数不是这样设置的   返回全局/窗口对象(即默认对象)   非严格模式,这不是通过调用设置的。)