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"}
複製代碼