JavaScript学习笔记——函数

二、函数

1 函数声明与函数表达式

function demo(){};
var demo = function(){};

2 立即调用函数

(function(){})();

3 arguments对象

4 this指的是谁

function sayNameForAll() {
 console.log(this.name);
}
var person1 = {
 name: "Nicholas",
 sayName: sayNameForAll
};
var person2 = {
 name: "Greg",
 sayName: sayNameForAll
};
var name = "Michael";
person1.sayName(); // outputs "Nicholas"
person2.sayName(); // outputs "Greg"
sayNameForAll(); // outputs "Michael"

5 改变this的指向call与apply

function sayNameForAll(label) {
 console.log(label + ":" + this.name);
}
var person1 = {
 name: "Nicholas"
};
var person2 = {
 name: "Greg"
};
var name = "Michael";
sayNameForAll.call(this, "global"); // outputs "global:Michael"
sayNameForAll.call(person1, "person1"); // outputs "person1:Nicholas"
sayNameForAll.call(person2, "person2"); // outputs "person2:Greg"

function sayNameForAll(label) {
 console.log(label + ":" + this.name);
}
var person1 = {
 name: "Nicholas"
};
var person2 = {
 name: "Greg"
};
var name = "Michael";
sayNameForAll.apply(this, ["global"]); // outputs "global:Michael"
sayNameForAll.apply(person1, ["person1"]); // outputs "person1:Nicholas"
sayNameForAll.apply(person2, ["person2"]); // outputs "person2:Greg"

6 执行上下文Context

一系列活动的执行上下文从逻辑上形成一个栈。栈底总是全局上下文,栈顶是当前(活动的)执行上下文。当在不同的执行上下文间切换(退出的而进入新的执行上下文)的时候,栈会被修改(通过压栈或者退栈的形式)。

7 函数执行过程

分为两个阶段:

第一阶段 进入执行上下文

函数的形参:其属性名就是形参的名字,其值就是实参的值;对于没有传递的参数,其值为undefined

函数声明:变量对象的一个属性,其属性名和值都是函数对象创建出来的;如果变量对象已经包含了相同名字的属性,则替换它的值

变量声明:变量对象的一个属性,其属性名即为变量名,其值为undefined;如果变量名和已经声明的函数名或者函数的参数名相同,则不会影响已经存在的属性。

第二阶段 执行代码

8 constructor和prototype

function Person(name) {
	this.name = name;
 	this.sayName = function() {
 		console.log(this.name);
 	};
}

var person1 = new Person("Nicholas");
var person2 = new Person("Greg");

console.log(person1.name); // "Nicholas"
console.log(person2.name); // "Greg"

person1.sayName(); // outputs "Nicholas"
person2.sayName(); // outputs "Greg"


function Person(name) {
 this.name = name;
}

Person.prototype.sayName = function() {
 console.log(this.name);
};

var person1 = new Person("Nicholas");
var person2 = new Person("Greg");

console.log(person1.name); // "Nicholas"
console.log(person2.name); // "Greg"

person1.sayName(); // outputs "Nicholas"
person2.sayName(); // outputs "Greg"



function Person(name) {
	this.name = name;
}
Person.prototype = {
	sayName: function() {
 		console.log(this.name);
 	},
	toString: function() {
 		return "[Person " + this.name + "]";
 	}
};

var person1 = new Person("Nicholas");

console.log(person1 instanceof Person); // true
console.log(person1.constructor === Person); // false
console.log(person1.constructor === Object); // true
修正后:

function Person(name) {
 this.name = name;
}
Person.prototype = {
	constructor: Person,
 	sayName: function() {
 		console.log(this.name);
 	},
 	toString: function() {
 		return "[Person " + this.name + "]";
 	}
};
var person1 = new Person("Nicholas");
var person2 = new Person("Greg");
console.log(person1 instanceof Person); // true
console.log(person1.constructor === Person); // true
console.log(person1.constructor === Object); // false
console.log(person2 instanceof Person); // true
console.log(person2.constructor === Person); // true
console.log(person2.constructor === Object); // false


9 闭包

一个计数器

var count = (function(){
   var num = 0;
   return function(){
      return num++;
   };
})();
var data = [];
 
for (var k = 0; k < 3; k++) {
  data[k] = function () {
    alert(k);
  };
}
 
data[0](); // 3, 而不是 0
data[1](); // 3, 而不是 1
data[2](); // 3, 而不是 2

修改:

var data = [];
 
for (var k = 0; k < 3; k++) {
  data[k] = (function _helper(x) {
    return function () {
      alert(x);
    };
  })(k); // 将 "k" 值传递进去
}
 
// 现在就对了
data[0](); // 0
data[1](); // 1
data[2](); // 2

提供函数外部访问函数内部变量的一种机制;

保存闭包形成时的上下文环境。

从理论角度:所有的函数。因为它们都在创建的时候就将上层上下文的数据保存起来了。哪怕是简单的全局变量也是如此,因为函数中访问全局变量就相当于是在访问自由变量,这个时候使用最外层的作用域。


从实践角度,以下函数才算是闭包:
① 即使创建它的上下文已经销毁,它仍然存在(比如,内部函数从父函数中返回);
② 在代码中引用了自由变量;

10 面试题

var num = 1;
var modify = function(){
   num = 2;
};

modify();
alert(num);

function modify(){
   num = 3;
} 
modify();
alert(num);

alert(x); // function
 
var x = 10;
alert(x); // 10
 
x = 20;
 
function x() {};
 
alert(x); // 20

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值