function call(){ [native code] }
Function.prototype.call = function () {
let param1 = arguments[0];
let paramOther = [ ]; //把arg中除了第一个之外的实参获取到
// this:fn 当前要操做的函数(函数类的一个实例)
// 把fn中的this关键字修改成param1 => 把this(call中)中的this关键字修改成param1
// 把fn执行,把paramOther分别传递给fn
// this(paramOther)
};
fn.call(obj);
复制代码
let sum = function (a,b) {
console.log(this);
};
let opt = { n: 20 };
// sum.call(opt, 20, 30); //=>call执行 call中的this是sum 把sum中的this关键字改成opt => sum中的this: opt a=20 b=30
sum.call.call(opt);
// 1.sum.call => 找到Function.prototype上的call方法(也是一个函数,也是函数类的一个实例,也能够继续调用call/apply等方法) ==>A(函数)
// 2.A.call(opt) => 继续找原型上的call方法,把call方法执行:把A中的this关键字修改成opt,把A执行
复制代码
// 原理分析:
Function.prototype.call = function callAA(){
//1.把this中的“this”关键字修改成第一个参数值obj
//2.把this(fn)执行,把第二个及之后接受的参数值传递给函数(10,20)
//this(10,20)
};
fn.call(obj,10,20);
复制代码
//执行题
function fn1(){
console.log(1);
};
function fn2(){
console.log(2);
};
fn1.call(fn2); //找到callAA 把它执行,callAA中的this是fn1,第一个参数传递的是fn2 => 在callAA中执行的是fn1 => 1
fn1.call.call(fn2); // 找到callAA让它执行,callAA中的this是fn1.call,第二个参数是fn2 (把fn1.call中的this变为fn2,再让fn1.call执行 => 先找到callAA,把它执行,只不过此时它中的this是fn2 => 让fn2中的this变为undefined,由于执行fn1.call的时候没有传递参数值,而后让fn2执行) => 2
Function.prototype.call(fn1); // 找到callAA让它执行,它中的this是Function.prototype => 让Function.prototype中的this变为fn1,而后让Function.prototype执行 => F.P是个匿名函数也是一个空函数,因此执行没有任何输出
Function.prototype.call.call(fn1); //它中的this是F.P.call => 把F.P.call中的this修改成fn1,让F.P.call执行 => F.P.call(callAA)第二次把它执行(此时它里面的this已是fn1 => 这一次在callAA中是让fn1执行 => 1
复制代码
//非严格模式
let fn = function (a, b) {
console.log(this, a, b);
};
let obj = {
name: 'obj'
};
fn.call(obj, 10, 20); // this:{...} a:10 b:20
fn.call(10, 20); // this:{10} a:20 b:undefined
fn.call(); // this:window a,b都是undefined
fn.call(null); // this:window a,b都是undefined
fn.call(undefined); // this:window a,b都是undefined
复制代码
"use strict" //严格模式
let fn = function (a, b) {
console.log(this, a, b);
};
let obj = {
name: 'obj'
};
fn.call(obj, 10, 20); // this:{...} a:10 b:20
fn.call(10, 20); // this:{10} a:20 b:undefined
fn.call(); // this:undefined a,b都是undefined
fn.call(null); // this:null a,b都是undefined
fn.call(undefined); // this:undefined a,b都是undefined
复制代码
const arr = [9, 6, 5, 60, 1, 20, 4, 16];
arr.sort(function (a, b) { //原地排序 不会返回新数组
return a - b;
});
console.log(arr);
console.log(arr[0]); // 最小值1
console.log(arr[arr.length - 1]); // 最大值60
复制代码
const ary = [9, 6, 5, 60, 1, 20, 4, 16];
let min = ary[0]; // 假设第一个是最小的
let max = ary[0]; // 假设第一个是最大的
for (let i = 1; i < ary.length; i++) {
let item = ary[i];
item < min ? min = ary[i] : null;
item > max ? max = ary[i] : null;
};
console.log(min);
console.log(max);
复制代码
获取一堆数中的最大值&最小值, 咱们须要将要比较的数字,要以一个一个实参的形式 传递到Math.max的方法里 才能正常使用javascript
//ES6扩展运算符 ...对象
var ary1 = [9, 6, 5, 60, 1];
console.log(Math.min(ary1)); // NaN
console.log(Math.min(...ary1)); // 1
console.log(Math.max(...ary1)); // 60
复制代码
//利用apply传参形式
var ary2 = [9, 6, 5, 60, 1];
console.log(Math.min.apply(null, ary2)); // 1
console.log(Math.max.apply(null, ary2)); // 60
console.log(Math.max.apply(null, [2, 6, 9])); // 9
复制代码
//数组转换成字符串,再进行字符串拼接
var ary3 = [9, 6, 5, 60, 1];
// var str = ary3.toString(); //'9, 6, 5, 60, 1'
var str2 = `Math.min(${ary3})`; //=>Math.min(9, 6, 5, 60, 1)
// var str2 = "Math.min("+ary3+")"; //=>Math.min(9, 6, 5, 60, 1)
console.log(eval(str2));
复制代码
"use strict"
let fn = function (a, b) {
console.log(this);
};
let obj = {
name: 'obj'
};
// document.onclick = fn; //=> 把fn绑定给点击事件,点击的时候执行fn,此时this:
// document.onclick = fn(); //=> 在绑定的时候,先把fn执行,把执行的返回值(此处的返回值是undefined)绑定给事件,当点击的时候执行的是undefined
//=> 需求:点击的时候执行fn,让fn中的this是obj
// document.onclick = fn; //=> this:obj
// document.onclick = fn.call(obj); //=> 虽然this确实改成obj,可是绑定的时候就把fn执行了(call是当即执行函数),点击的时候执行的是fn的返回值undefined
document.onclick = fn.bind(obj); //=> bind属于把fn中的this预处理为obj,此时fn没有执行,当点击的时候才会把fn执行 此时this:{name: "obj"}
复制代码