제2장this,call,apply

6495 단어

제2장this,call,apply


2.1 this


2.1.1 this의 행방


1 대상 방법으로 호출
var obj = {
    a:1,
    getA:function(){
        console.log(this === obj);  //true
        console.log(this.a); //1
    }
}
obj.getA();

2 일반 함수로 호출
// 
window.name = 'globalName'

var getName = function(){
    return this.name;
}

console.log(getName()); //globalName

// 

window.name = 'globalName'

var myObject = {
    name:'sven',
    getName:function(){
        return this.name;
    }
}
var getName = myObject.getName;
console.log(getName());  //globalName





    
div
window.id = 'window'; document.getElementById('div1').onclick = function(){ alert(this.id); //div1 var callback = function(){ alert(this.id); //window } callback();// }

div 결점의 인용 저장
document.getElementById('div1').onclick = function(){
    var that = this;
    var callback = function(){
    alert(this.id);  //div1
    }
    callback();
}

es5의strict 모드에서 이러한 경우this는 전역 대상을 가리키지 않고undefined로 규정되어 있습니다
function func() {
    'use strict'
    alert(this); //undefined
}
func

3 구조기 호출
var Mycalss = function(){
    this.name = 'sven'
    return 'anne';
}
var obj = new Mycalss();
alert(obj.name);  //sven

Object 형식을 현저하게 되돌려줍니다.
var Mycalss = function(){
    this.name = 'sven';
    return {
        name:'anne'
    }
}
var obj = new Mycalss();
alert(obj.name);  //anne

4Function.prototype.call 또는 Function.prototype.apply 호출 동적 전송 함수this
var ob1 = {
    name:'sven',
    getName:function(){
        return this.name;
    }
}
var obj2 = {
    name:'anne'
}
console.log(obj1.getName());//sven
console.log(obj1.getName(obj2));//anne

2.1.2 잃어버린 this

var myObject = {
    name:'sven',
    getName:function(){
        return this.name;
    }
}
console.log(myObject.getName());//sven
var getName2 = myObject.getName;
console.log(getName2());//undefined


    
        
div
var getId = document.getElementById; getId('div1'); // document.getElementById = (function(func){ return function(){ return func.apply(document,arguments); } })(document.getElementById); var getId = document.getElementById; var div = getId('div1'); alert(div.id); //div1

2.2call 및 apply


2.2.1call과 apply의 차이


apply는 두 개의 매개 변수를 받아들인다. 첫 번째 매개 변수는 함수 체내의this 대상의 지향을 지정하고 두 번째 매개 변수는 밑에 표시된 집합이다. 이 집합은 수조로 할 수도 있고 클래스로 할 수도 있다. apply 방법은 집합 중의 요소를 매개 변수로 호출된 함수에 전달한다.
var func = function(a,b,c){
    alert([a,b,c]); //[1,2,3]
}
func.apply(null,[1,2,3]);

ll이 전송하는 매개 변수는 고정되지 않습니다. apply와 같은 것은 첫 번째 매개 변수도 함수 체내의this지향을 대표하고 두 번째 매개 변수부터 뒤로 매개 변수는 순서대로 함수를 전달합니다.
var func = function(a,b,c){
    alert([a,b,c]); //[1,2,3]
}
func.call(null,1,2,3);

call은 apply에 포장된 문법사탕으로 함수가 얼마나 많은 파라미터를 받아들일지 명확하게 알고 일목요연하게 표현형이 실삼의 대응 관계에 참여하려면 call로 파라미터를 전달할 수도 있다.
콜과 apply를 사용할 때, 우리가 사람을 전송하는 첫 번째 인자가null이면 함수 내의this는 기본 숙주 대상을 가리키고 브라우저에서는 window를 가리킨다.
var func = function(a,b,c){
    alert(this == window); //true
}
func.call(null,1,2,3);

엄격 모드 또는 null
var func = function(a,b,c){
    alert(this === null); //true
}
func.call(null,1,2,3);

어떤 구체적인 대상을 대신할 사람을 null로 소환하다
Math.max.apply(null,[1,2,3,5,4])  //5

2.2.2call과 apply의 용도


1 this가 var obj1을 가리키도록 변경 = {name:'sven'}
var obj2 = {
    name:'anne'
}

window.name = 'window'
var getName = function(){
    alert(this.name);
}
getName();
getName.call(obj1);
getName.call(obj2);


document.getElementById('div1').onclick = function(){
    var func = function(){
        alert(this.id)  //div1
    }
    func.call(this);
}

2Function.prototype.bind
Function.prototype.bind = function(content){
    var self = this;
    return function(){
        return self.apply(context,arguments);
    }
};
var obj = {
    name:'sven'
}
var func = function(){
    alert(this.name); //sven
}.bind(obj);
func();

복잡하다 복잡하다
Function.prototype.bind = function(){
    var self = this,
        context = [].shift.call(arguments),
        args = [].slice.call(arguments);
    return function(){
        return self.apply(context,[].concat.call(args,[].slice.call(arguments)));
    }
};
var obj = {
    name:'sven'
}
var func = function(a,b,c,d){
    console.log(this.name); //sven
    console.log([a,b,c,d]); //[1,2,3,4]
}.bind(obj,1,2);
func(3,4);

3 다른 객체를 대여하는 방법
var A = function(name){
    this.name = name;
}
var B = function(){
    A.apply(this,arguments);
}
B.proto.getName = function(){
    return this.name;
}
var b = new B('sven');
console.log(b.getName()) //sven

arguments에 새 요소를 추가합니다. 보통 Array를 빌려씁니다.prototype.push:
(function(){
    Array.prototype.push.call(arguments,3);
    console.log(arguments); //[1,2,3]
})(1,2)

arguments가 진정한 그룹으로 바뀌었습니다. Array.prototype.slice; 첫 번째 원소인 Array를 자르세요.prototype.shift;
V8 엔진 소스 Array.prototype.push
function ArrayPush(){
    var n = TO_UINT32(this.length); // push length
    var m = %_ArgumentsLength(); //push 
    for(var i = 0; i < m; i++){
        this[i+n] = %_Arguments(i); // 
    }
    this.length = n + m;
    return this.length;
}

대상이 수조인지 유수조인지는 조금도 중요하지 않아, '임의' 대상을 사람에게 전할 수 있다
var a = {}
Array.prototype.push.call(a,'first');
alert(a.length);//1
alert(a[0]); //first

저버전 IE 브라우저에서 실행하려면 객체 a에 length 속성을 명시적으로 설정해야 합니다.
var a = {
  length:0
};

대상 자체는 속성 대상의length 속성 읽기와 쓰기를 접근할 수 있어야 한다
var a = 1;
Array.prototype.push.call(a.'first');
alert(a.length);//undefined
alert(a[0]);//undefined

var func = function(){};
Array.prototype.push.call(func,'first');
alert(func.length)// 

좋은 웹페이지 즐겨찾기