- 函数内部this的指向的几种情况
- 改变函数内部的this(call、bind、apply的区别)
函数基础
创建和调用函数
- 函数声明:
function 函数名(形参){// 函数体中的代码 }
- 函数表达式:
var 函数名 = function(形参){// 函数体中的代码 }
- 调用
函数名(实参)
函数的参数
- 形参:函数定义时,标识符,可以理解为函数内部的局部变量
- 实参:函数调用时,实际的数据
函数的返回值
- 关键字:return
- 函数内部默认没有写return,默认返回undefined
- 作用:返回值,结束函数执行。
作用域
-
全局作用域
- 函数之外的执行环境
- 全局变量:可以在任何地方使用。
-
局部作用域
- 函数内部的执行环境
- 局部变量:仅仅只能在函数内体使用
- 注意:把形参理解为局部变量
-
作用域链:
在访问一个变量时,会先从本作用域中去找,若找不到,则找向上层作用域,以此类推。
变量提升
- 把var关键字声明变量名,仅仅是变名,提升到当前作用域的顶部,所以在当前作用于只能访问到该变量名,而不能访问到变量所代表的值。
- 函数声明创建的函数整体会提升到当前作用域顶部
匿名函数和自调用函数
- 没有名字的函数
- 匿名函数一般要配合运算符使用,否则语法报错,比如在
function
前加+
- 匿名函数定义好之后,要马上调用,否则没有意义。
- 匿名函数一般要配合运算符使用,否则语法报错,比如在
- 自调用函数
- 注意:有名字的或匿名的函数都可以自调用。
- 匿名函数的作用:
- 可以避免全局变量污染。(命名冲突)
- 可以模拟块级作用域。
- 递归调用:
- arguments.callee()
- 严格模式下:用小名
var recursion=function fn(){fn()}
一. 函数也是对象
-
函数的另外一种创建方式
- 语法:
==var 变量名 = new Function('参数1','参数2',...,'函数体中的代码');==
-
代码:
//【函数声明】 function fn(a,b) { console.log(a + b); console.log(a + b); console.log(a + b); console.log(a + b); } fn(10,20); // 函数是一种数据类型吗? // 答:是,类型 Function // new关键字-创建方式 // 语法:var 变量名 = new Function('参数1','参数2',...,'函数体中的代码'); //var fn = new Function('a','b','console.log(a + b);'); // 调用 // fn(10,20); // 扩展:eval('字符串代码'); 把字符串代码解析成真正意义的js代码执行 // 'alert(1)'; // eval('alert(1)');
二. 函数内部this的指向
在此,this是在函数内部研究
函数内部的this不是在函数定义时决定的,而是在函数调用执行时决定的。
2.1 普通函数中this的指向
function fn() {
console.log(this);
}
fn(); // window
var fn = function(){
console.log(this);
};
fn(); // window
(function(){
console.log(this);
})(); // window
function fn1() {
var fn2 = function() {
console.log(this);
}
fn2(); // window
}
fn1();
2.2 定时器中this的指向
【定时器中的this指向window】
setTimeout(function(){
console.log(this);
},10);
2.3 构造函数中this指向
this指向当前创建的对象。 要去理解new关键字的创建过程
function Student(name,age) {
this.name = name;
this.age = age;
}
Student.prototype.sayHi = function() {
console.log('我叫' + this.name);
};
var stu1 = new Student('张三',18);
var stu2 = new Student('李四',18);
2.4 方法中this指向
this指向方法的调用者。
function Student(name,age) {
this.name = name;
this.age = age;
}
Student.prototype.sayHi = function() {
console.log('我叫' + this.name);
};
var stu1 = new Student('张三',18);
var stu2 = new Student('李四',18);
// 【在调用一个方法时→对象.方法名(); 方法内部this指向调用者】
stu1.sayHi(); // 张三
stu2.sayHi(); // 李四
2.5 事件处理程序中this指向
this指向事件源。 事件触发后(函数才会执行)才知道
// 【事件处理程序→ this指向事件源】
document.onclick = function() {
console.log(this); // document
};
三. 改变this的指向
3.1 call方法
-
语法:==函数名.call(调用者,参数1...)==
-
作用:函数被借用时,会立即执行,并且函数体内的this会指向借用者或调用者
-
代码:
// 定义一个函数 function fn(name, age) { this.name = name; this.age = age; } // 定义一个自己的对象 var obj = {}; // 字面量 fn.call(obj, '李四', 10);
3.2 apply方法
-
语法:==函数名.apply(调用者,[参数1...])==
-
作用:函数被借用时,会立即执行,并且函数体内的this会指向借用者或调用者
-
代码:
// 定义一个函数 function fn(name, age) { this.name = name; this.age = age; } // 定义一个自己的对象 var obj = {}; // 字面量 fn.apply(obj, ['李四', 10]);
3.3 bind方法
-
语法:==函数名.bind(调用者,参数1...)==
-
作用:函数被借用时,不会立即执行,而是返回一个新的函数。需要自己手动调用新的函数。
- 返回新函数
-
代码:
// 定义一个函数 function fn(name, age) { this.name = name; this.age = age; } // 定义一个自己的对象 var obj = {}; // 字面量 fn.bind(obj, '李四', 10)();
应用
-
伪数组借用数组的push方法实现增加
-
使用Math对象max方法取出数组中的最大数字
-
作业:伪数组借用数组的reverse方法实现反转
四.函数的其他属性
-
函数名.arguments
获取用户传入的实参
-
函数名.length
获取函数形参的个数
-
函数名.name
函数的名字
网友评论