call,appyとbind
19169 ワード
thisを学ぶ時、いくつかの方法のcallを見ました.applyとbindにもう一つのnew演算子があります.それらの概念と原理を勉強しました.
Funtion.prototype.cal()
function.call(thisArg,arg 1,arg 2...)関数は、指定されたthis値と個別に与えられた1つ以上のパラメータを使用して呼び出されます.戻り値は、this値とパラメータが指定された関数を呼び出した結果です.厳密でないモードでは、thisArgがnullまたはundefinedであれば、自動的にグローバルオブジェクト2.thisArgに置き換えられます.コールは自動的に元のデータタイプに変換されます.
function.applyは、指定されたthis値と配列オブジェクト(またはクラスオブジェクト)を使用して関数を呼び出します.非厳密モードでは、thisArgがnullまたはundefinedであれば自動的にグローバルオブジェクトに置き換えられ、戻り値は、指定されたthis値とパラメータの関数を呼び出した結果です.
function.bindは新しい関数を作成します.新しい関数のthisはbindの最初のパラメータに指定されます.残りのパラメータは新しい関数のパラメータとして、ソース関数のコピー関数を返して、指定されたthis値とパラメータを持ちます.したがって、bindを呼び出すには関数3が必要です.newを使って、bindから返される関数を呼び出した場合、thisはソース関数構造関数の例を指します.
new constructor[(argments)]constructorの指定されたインスタンスのタイプのクラスまたは関数argmentsパラメータリストnew演算子がユーザ定義のオブジェクトタイプのインスタンスを作成するか、または構築関数内蔵のオブジェクトのインスタンスnewキーワードが次の操作を行います.新しいオブジェクトを作成します. このオブジェクトの_uをプロト.この構造関数を指すプロトタイプ このオブジェクトを関数とするthisのコンテキスト このコンストラクションがオブジェクトに戻らない場合、この新しいオブジェクト に戻ります.
Funtion.prototype.cal()
function.call(thisArg,arg 1,arg 2...)関数は、指定されたthis値と個別に与えられた1つ以上のパラメータを使用して呼び出されます.戻り値は、this値とパラメータが指定された関数を呼び出した結果です.厳密でないモードでは、thisArgがnullまたはundefinedであれば、自動的にグローバルオブジェクト2.thisArgに置き換えられます.コールは自動的に元のデータタイプに変換されます.
// call
var animals = [
{
species: 'Lion', name: 'King' },
{
species: 'Whale', name: 'Fail' }
];
for (var i = 0; i < animals.length;i++){
(function (i) {
this.point = function () {
console.log(`#${
i}:${
this.species}+${
this.name}`)
}
}).call(animals[i],i)
}
//
原理Function.prototype.myCall = function (context) {
/** null undefined, this window/global */
/** null undefined, */
if (!context) {
// window global
context = typeof window === 'undefined' ? global : window;
}else{
context = Object(context)
}
context.fn = this; //this (Function )
let rest = [...arguments].slice(1);// this , slice
let result = context.fn(...rest); // , this context.
delete context.fn; //
return result; //
}
テストvar foo = {
name: 'Selina'
}
var name = 'Chirs';
function bar(job, age) {
console.log(this.name);
console.log(job, age);
}
bar.myCall(foo, 'programmer', 20); //Selina, programmer , 20
bar.myCall(null, 'programmer', 20); //Chirs, programmer , 20
Function.prototype.apple()function.applyは、指定されたthis値と配列オブジェクト(またはクラスオブジェクト)を使用して関数を呼び出します.非厳密モードでは、thisArgがnullまたはundefinedであれば自動的にグローバルオブジェクトに置き換えられ、戻り値は、指定されたthis値とパラメータの関数を呼び出した結果です.
// apply
let charArr = ['a','b','c']
let numArr = [1,2,3]
numArr.push.apply(numArr,charArr)
console.log(numArr) //[1 , 2 , 3 , 'a' , 'b' ,'c']
原理はコールに似ています.Function.prototype.myApply = function(context,rest){
//
if(!context){
// call , null undefined ,
context = typeof window === undefined ? global : window
}else{
context = Object(context)
}
context.fn= this
let result;
if(rest === undefined || rest === null){
// undefined null ...
result = context.fn(rest)
} else if (rest instanceof Object ){
result = context.fn(...rest)
}
delete context.fn //
return result
}
テスト//
var foo = {
name: 'Selina'
}
var name = 'Chirs';
function bar(job, age) {
console.log(this.name);
console.log(job, age);
}
bar.myApply(foo, ['programmer', 20]); //Selina programmer 20
bar.myApply(null, 'teacher', 25);
// : Chirs teacher 25; node : undefined teacher 25
Function.prototype.bind()function.bindは新しい関数を作成します.新しい関数のthisはbindの最初のパラメータに指定されます.残りのパラメータは新しい関数のパラメータとして、ソース関数のコピー関数を返して、指定されたthis値とパラメータを持ちます.したがって、bindを呼び出すには関数3が必要です.newを使って、bindから返される関数を呼び出した場合、thisはソース関数構造関数の例を指します.
Function.prototype.myBind = function (thisArg,...rest) {
//
if (typeof this !== 'function') throw new TypeError("invalid invoked!");
let self = this
//
return function F(...args) {
console.log(this)
if(this instanceof F){
// new this
return new self(...rest,...args)
//
}
//
return self.apply(thisArg,[...rest,...args])
}
}
テストvar name = 'window'
function fn(name) {
// console.log(this)
console.log(this.name)
console.log(name)
}
let obj = {
name:'obj'
}
let f= fn.myBind(obj)
f(' ') //obj
let nF = new f(' ') // undefined
new操作子new constructor[(argments)]constructorの指定されたインスタンスのタイプのクラスまたは関数argmentsパラメータリストnew演算子がユーザ定義のオブジェクトタイプのインスタンスを作成するか、または構築関数内蔵のオブジェクトのインスタンスnewキーワードが次の操作を行います.
function Person(name,age) {
this.name = name
this.age = age
}
let p = new Person(' ',23)
console.log(p) //Person {
name: ' ', age: 23 }
原理function myNew(fun, ...arg) {
//
const result = {
};
// __proto__
result.__proto__ = fun.prototype
fun.prototype.constructor == fun
// (this)
const res = fun.apply(result, arg);
//
if(res&&res instanceof Object){
return res
}
//
return result;
}
テストfunction Person(name,age) {
this.name = name
this.age = age
}
let p = myNew(Person,' ',22)
console.log(p) //Person {
name: ' ', age: 22 }
function Person(name,age) {
this.name = name
this.age = age
return {
}
}
let p = myNew(Person,' ',22)
console.log(p) //{
}