原型 (对象) 方法
-
apply()
var name = 'hx'; var obj = { name: 'huangxin', fn: function() {var f = function(a,b) {console.log(this.name,a,b) } return f.call({name:'hxin'},'lala','fafa'); } } obj.fn(); // hxin lala fafa
-
call()
var name = 'hx'; var obj = { name: 'huangxin', fn: function() {var f = function(a,b) {console.log(this.name,a,b) } return f.apply({name:'hxin'},['lala','fafa']); } } obj.fn(); // hxin lala fafa
思考 1 :如果 apply 或 call 的第一个参数传 null 的话,结果会是什么?
答案:hx lala fafa
思考 2 :如果我希望输出是:huangxin lala fafa,该如何实现?
答案:使用箭头函数
var f = (a,b) => console.log(this.name,a,b)
思考 3 :箭头函数和 call、apply 这种改变 this 指向的方法混用时,由谁主导?
答案:由箭头函数主导,call 等方法失效
-
bind()
var name = 'hx'; var obj = { name: 'huangxin', fn: function() {var f = function(a,b) {console.log(this.name,a,b) } return f.bind({name:'hxin'})('lala','fafa'); } } obj.fn(); // hxin lala fafa
Attention:bind 只作用于直接调用它的函数
var name = 'hx';
var obj = {
name: 'huangxin',
fn: function() {console.log(this.name);
}
}
obj.fn.bind({name:'hxin'})();
// hxin (bind 生效,this 指向特定对象)
var name = 'hx';
var obj = {
name: 'huangxin',
fn: function() {console.log(this);
var f = function() {console.log(this.name)
}
return f();}
}
obj.fn.bind({name:'hxin'})();
// {name: "hxin"} (bind 生效,this 指向特定对象)
// hx (bind 不生效,this 指向 Window。原因:调用 bind 方法的是函数 fn,而不是 f,执行 f()时,依旧是按普通函数对待的)
原型 (对象) 属性
-
callee
// 代表函数自身,在递归中为了避免函数被重命名导致递归错误 function recursion(num) {if (num <= 1) {return 1;} else {return num * recursion(num - 1); } } var other = recursion; recursion = null; other(6); // Uncaught TypeError: recursion is not a function // 用 callee 改进原函数 function recursion(num) {if (num <= 1) {return 1;} else {return num * arguments.callee(num - 1); } } var other = recursion; recursion = null; other(6); // 720
-
arguments
// 代表传入函数的实参,类 Array 类型 function fn() {console.log(arguments); console.log(arguments.length); } fn(1,2,3); // [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ] // 3
-
length
function a(a){} function b(){} function c(a,c){} function d(a,b=1,c){} function e(a=1,b,c){} console.log(a.length); // 1 console.log(b.length); // 0 console.log(c.length); // 2 console.log(d.length); // 1 console.log(e.length); // 0
-
name
console.log((function a(){}).name) // a console.log((new Function).name) // anonymous
Tips:一个综合用例
// 修改默认全局函数 parseInt,使之可以统计代码调用了几次 parseInt
var count = 0;
var oldParseInt = parseInt;
window.parseInt = function() {
count += 1;
return oldParseInt.apply(null,arguments)
}
parseInt(11.4); // 11
parseInt('10.9'); // 10
console.log(count); // 2
Attention:arguments 是类数组,不是数组
var a;
function fn() {
a = arguments;
return parseInt(arguments);
}
fn(10.5);
// NaN
function fun() {return parseInt.apply(null,arguments);
}
fun(10.5);
// 10
console.log(a);
// Arguments [10.5, callee: ƒ, Symbol(Symbol.iterator): ƒ]
parseInt([10.5]);
// 10
parseInt(a);
// NaN
parseInt.apply(null,a);
// 10