> 웹 프론트엔드 > JS 튜토리얼 > Javascript 이 키워드 사용 분석_javascript 기술

Javascript 이 키워드 사용 분석_javascript 기술

WBOY
풀어 주다: 2016-05-16 18:59:46
원래의
898명이 탐색했습니다.

js에는 this 키워드에 대한 많은 기사가 있습니다. 이 기사를 쓰는 목적은 예제를 통해 이 키워드의 작동 원리를 분석하는 것입니다.

1. 기본:

코드 복사 코드는 다음과 같습니다.

function doSomething(){
alert(this.id);
}
alert(window.doSomething);//doSomething이 window에 속함을 증명합니다
doSomething();// 정의되지 않음
window.onload = function(){
document.getElementById("div2").onclick = doSomething;//div2
document.getElementById("div3").onclick = function(){doSomething ( );}//정의되지 않음
}

1. doSomething 함수의 경우:
코드 복사 코드는 다음과 같습니다.

function doSomething(){
alert(this.id)
}

이 함수는 전역 함수, this 전역 함수는 실제로 window에 속합니다(window.doSomething을 통해 액세스할 수 있음). 직접 호출되는 경우 "this는 항상 우리가 실행 중인 함수의 "소유자"를 참조합니다"에 따르면 다음과 같습니다. 함수에는 window가 있습니다. 그러나 window에는 id 속성이 없으므로 "정의되지 않음"이 표시됩니다.

2. html 요소에서 이를 호출합니다.
코드 복사 코드는 다음과 같습니다.
div1

이 "정의되지 않음"도 표시되며 이는 다음 코드와 동일합니다.

코드 복사 코드는 다음과 같습니다.
document.getElementById("div1").onclick = function(){doSomething();}

div1을 클릭하면 window에 속한 doSomething 함수가 호출되므로 "undefine"도 표시됩니다.

3. div2가 로드된 후:

코드 복사 코드는 다음과 같습니다.
document.getElementById("div2").onclick = doSomething

div2를 클릭하면 div2의 onclick에 값이 할당되므로 "div2"가 표시됩니다. 이때 복사된 함수는 div2에 속하며 window에 속한 doSomething과 관련이 없습니다. . div2를 클릭하면 div2에 속한 doSomething이 트리거됩니다. 여기서는 div2를 나타냅니다.

2.attachEvent 및 addEventListener

attachEvent는 IE에서 이벤트를 바인딩하는 방법입니다. 해당 함수를 전역 세계에 복사합니다(즉, 응답 함수의 소유자는 창입니다). , 그러나 DOM 표준에서는 addEventListener가 이벤트를 바인딩할 때 복사된 응답 함수의 소유자는 이벤트에 바인딩된 객체입니다.

코드 복사 코드는 다음과 같습니다.
function doSomething(){
alert(this.id)
alert(this == window)
>window.onload = function(){
var div1 = document.getElementById("div1")
if(div1.attachEvent){
div1.attachEvent("onclick",doSomething); >document.body.appendChild(document.createTextNode ("attachEvent"));
}else if(div1.addEventListener){
div1.addEventListener("click",doSomething,false)
document. body.appendChild(document.createTextNode("addEventListener "));
}else{
div.onclick = doSomething;
}
}



function doSomething



코드 복사 코드는 다음과 같습니다. function doSomething(){
alert(this.id);
alert(this == 창)
}


1. div1의 클릭 이벤트에 바인딩하려면 doSometing이 창에 복사됩니다. 이때 doSomething에서는 div1을 클릭하면 "undefine" 및 "true"가 됩니다. 표시

2. addEventListener를 사용하여 div1의 클릭 이벤트를 바인딩합니다. 이때 복사한 함수는 div1에 속하므로 div1을 클릭하면 "div1"과 "false"가 표시됩니다. 🎜>
참고: http://www.quirksmode.org/js/this.html에서는 attachmentEvent가 함수 참조만 사용한다고 믿습니다.

var obj = new Object()
obj.color = "black"
obj; .showColor = function(){
경고(this.color);
경고(this == 창)
obj.showColor(); document.getElementById("div1");
div1.attachEvent("onclick",obj.showColor);


이때 div1을 클릭하면 "undefine" 및 "true"가 됩니다. AttachEvent가 obj.showColor만 참조하는 경우 이는 여전히 obj를 참조해야 하지만 실제로는 창을 참조하므로 참조가 아니라 전역 항목에 대한 복사본이라고 생각합니다.

3. 객체 가장의 상속 방식에 대하여
1. new와 not new의 차이점

다음 기능에 대해




코드 복사
코드는 다음과 같습니다. function ClassA(sColor){ this.color = this; .sayColor = function() {
alert(this.color);
}
}


이것은 클래스인가요, 아니면 함수인가요? 그것은 당신에게 달려 있습니다!

이것이 함수라고 생각한다면 다음과 같이 호출할 수 있습니다.
ClassA("red")
"red"는 ClassA에서 전달되는 매개변수입니다. 물론 window에도 있으므로 이제 window에는 색상 속성과 sayColor 메서드가 있고 색상 값은 "red"입니다.

sayColor 또는 window.sayColor를 호출하여 "red"를 표시하는 것입니다.

window.sayColor()


이것이 클래스라고 생각한다면, 그런 다음 다음과 같이 사용해야 합니다.

var obj = new ClassA("red");
new 키워드가 등장하면 위 코드에 많은 내용이 추가됩니다. 먼저 Object 인스턴스를 만듭니다. 그런 다음 ClassA에서 생성된 개체를 가리키고 마지막으로 이 개체를 반환하므로 반환된 개체가 obj에 할당됩니다. 따라서 이것이 obj를 가리키고, obj는 color 속성과 sayColor 메서드를 가지며, color 속성 값은 "red"라고 말할 수 있습니다.

2. 함수 소유자




코드 복사
코드는 다음과 같습니다. function showId(){ alert(this.id); }
window.onload = function(){
var div1 = document.getElementById("div1")
div1 .onclick = showId;
div1.show = showId;

var obj = new Object()
obj"; >obj .show = showId;
obj.show();
}


showId 함수를 클릭 이벤트 또는 모든 개체의 속성에 할당할 수 있습니다. 또한 showId 메서드를 복사하므로 div1.show 메서드를 호출하면 이것이 div1을 가리키고 obj.show를 호출하면 this는 obj를 가리킵니다.

3. 객체 가장의 원리 ​​

다음 코드는 객체 가장 방법을 통해 구현된 상속입니다



코드 복사


코드는 다음과 같습니다. }

function ClassB(sColor,sName){
this.newMethod = ClassA; >newMethod;

this.name = sName;
this.sayName = function(){
alert(this.name);
var objB = new ClassB("objB의 색상","objB의 이름")
objB.sayColor()


objB는 ClassB의 인스턴스입니다. objB는 어떻게 color 속성과 sayColor 메서드를 갖나요?

먼저 인스턴스화 코드를 살펴보세요.

var objB = new ClassB("color of objB","name of objB")

여기서 ClassB는 클래스입니다. 물론 ClassB에서 이것은 객체 objB를 참조합니다.

ClassB에서 코드의 처음 세 줄은 ClassA를 사용하고 ClassA는 클래스가 아닌 함수로 간주됩니다.

ClassA 함수를 직접 호출하면 ClassA의 this는 윈도우 객체를 참조하므로 먼저 ClassA를 objB의 newMethod 속성에 복사합니다(this.newMethod = ClassA).

그런 다음 this.newMethod를 호출합니다. 이는 이 메서드의 소유자가 분명히 this이고 ClassB의 this는 현재 objB를 참조하므로 현재는 ClassA에 있습니다(엄밀히 말하면 this가 복사되므로 newMethod에 있습니다). 이미 ClassA에 두 개의 메서드가 있습니다. 이는 objB를 참조합니다. 이러한 방식으로 newMethod 호출을 통해 color 속성과 sayColor 메서드가 objB에 할당됩니다. 호출 및 적용 메소드를 사용하여 상속을 구현하는 것은 실제로 원칙입니다. 호출 및 적용은 메소드 소유자를 변경하는 메소드로 간주할 수 있으며 여기서 ClassB의 처음 세 줄이 이 역할을 합니다.

4. 프로토타입1.6의 Class.create
코드 복사 코드는 다음과 같습니다.

prototype1.6의 Class.create 메소드는 대략 다음과 같습니다.

var Class = {
create: function() {
//

function klass() {
this.initialize.apply(this, 인수)
}

//

for (var i = 0; i < Properties.length ; i )
klass.addMethods(properties[i]);

return klass;


사용 중 다음과 같습니다.





코드 복사
코드는 다음과 같습니다. var Person = Class.create({ initialize:function(name){
this.name = name;
},
say:function(message){
Alert(this.name " :" message);
}
});

var aPerson = new Person("name1")
aPerson.say("hello1");


Person은 실제로 Class.create 메소드에 의해 반환된 클래스이고(klass는 함수인 Class.create의 지역 변수입니다), Class.create에 의해 전달된 매개변수(초기화 메소드 및 say 메소드) )이 메소드의 속성 배열에 생성되도록 전달되고 klass 프로토타입이 addMethods 메소드를 통해 이러한 메소드를 갖도록 합니다. 따라서 가장 중요하고 가장 이해하기 어려운 점은 klass에서 이것이 정확히 무엇을 참조하는지입니다. 잘 생각해보면 답을 얻는 것은 어렵지 않습니다. Person은 실제로 클래스이며 Person 객체를 인스턴스화할 때 다음과 같은 new 키워드를 사용합니다.

var aPerson = new Person("name1" ) ;

이것은

var aPerson = new klass("name1");

klass는 외부에서 접근할 수 없지만 내부에서는 쉽게 접근할 수 있습니다. 이 방법으로 문제를 설명하면 klass는 단순한 함수가 아닌 클래스입니다(new 키워드가 사용되었기 때문에 그렇게 생각합니다). 그러면 klass의 this는 선언된 인스턴스를 참조합니다. 여기서는 aPerson이고, aPerson은 klass의 프로토타입을 전달합니다. 초기화 메소드와 say 메소드를 가질 수 있습니다. 새로운 프로세스 동안 klass의 코드도 실행되므로 인스턴스화될 때, 즉 생성자가 실행됩니다. (klass의 두 this 모두 aPerson을 참조합니다. Apply를 통해 한 번 호출해야 하는 이유는 무엇입니까? 이는 주로 생성자의 매개변수를 전달하기 위한 것입니다. Apply 메소드를 사용하면 무한한 수의 매개변수를 편리하게 전달하여 배열을 통해 초기화할 수 있습니다. . Method. )

5. 몇 가지 예시를 더 분석해 보겠습니다.

다른 글에서 본 예시를 분석해 보겠습니다.

다음과 같이 실행하세요




코드 복사
코드는 다음과 같습니다. function OuterFoo(){ this.Name = ' 외부 이름';
function InnerFoo(){
var Name = '내부 이름';
alert(Name ', 'this.Name)
}
return InnerFoo;
}
OuterFoo()()


표시된 결과는 "내부 이름, 외부 이름"입니다.

OuterFoo는 함수(클래스가 아님)이고 첫 번째 문장

this.Name = 'Outer Name'; in

은 window 객체를 참조하므로 OuterFoo() window.Name = 'Outer Name';

이후에는 InnerFoo도 함수입니다(클래스가 아닙니다). ), InnerFoo를 실행할 때 이는 창도 참조하므로 InnerFoo의 this.Name 값은 "외부 이름"입니다(window.Name은 전송 스테이션 역할을 하여 OuterFoo가 "외부 이름" 값을 InnerFoo에 전달할 수 있도록 함). Name 값은 지역 변수 "Inner Name"입니다.

2. 다음 코드를 실행합니다.


코드 복사 코드는 다음과 같습니다.

function JSClass(){

this.m_Text = 'division element'
this.m_Element = document .createElement( 'DIV');
this.m_Element.innerHTML = this.m_Text;

if(this.m_Element.attachEvent)
this.m_Element.attachEvent('onclick', this. ToString);
else if(this.m_Element.addEventListener)
this.m_Element.addEventListener('click', this.ToString,false)
else
this.m_Element.onclick = this. ToString;
}

JSClass.prototype.Render = function(){
document.body.appendChild(this.m_Element);

JSClass.prototype. ToString = function (){
alert(this.m_Text);
alert(this == window)
}

window.onload = function(){
var jc = new JSClass ();
jc.Render();
jc.ToString();
}

"division 요소"를 클릭하면 "정의되지 않음"이 표시됩니다. IE에서도 필요하며 "true"를 표시하고 다른 브라우저도 "false"를 표시합니다.

인스턴스 선언 및 인스턴스 메소드 호출에 대해서는 딱히 할 말이 없습니다. 요소의 click 이벤트는 인스턴스 메소드에 바인딩되어 있으므로 addEventListener를 통해 바인딩된 메소드가 복사되므로 html 요소를 참조합니다. 이 요소에는 m_Text 속성이 없습니다(m_Text 속성은 JSClass 인스턴스, 즉 jc에 속함). 따라서 해당 요소를 클릭하면 AttachEvent에 바인딩된 이벤트가 함수를 전역 세계에 복사합니다. 이 요소를 클릭하면 "정의되지 않음"이 표시됩니다. jc.ToString() 메소드가 호출될 때만 jc 객체를 참조합니다. jc는 m_Text를 소유하므로 "division 요소"를 표시할 수 있습니다.

6. 요약

코드 환경에서 이것이 가리키는 객체를 빠르게 찾는 방법은 무엇일까요? 다음 세 가지 측면에 주목하고 싶습니다.
1. 함수의 각 단계가 복사인지 참조(호출)인지 명확하게 알아야 합니다.
2. 함수의 소유자는
3. 함수의 경우 함수로 사용하는지, 아니면 클래스로 사용하는지 파악해야 합니다.

보충:
1. 인스턴스와 클래스 모두
2. 프로토타입을 사용하여 인스턴스에 함수를 정의할 수는 없으며, 프로토타입을 사용하여 클래스에 함수를 정의할 수만 있습니다
3. 클래스에 직접 정의된 함수는 이를 사용하여 객체의 속성에 액세스할 수 없습니다.
4. 클래스의 프로토타입에서는 생성된 함수가 이것을 사용할 수 있고, 클래스 내에 정의된 함수가 이것을 사용할 수 있으며, 객체 인스턴스에서 생성된 함수가 이것을 사용할 수 있습니다.

복사 code 코드는 다음과 같습니다:
window.alert=function (msg)
{
document.write(msg "
");
}
함수 say()
{
this.f="props";
this.func3=function(){alert("f3," this.f) ;}
}
say .func1=function(){alert("func1," this.f);}; //오류, 클래스에 직접 정의된 함수는 사용할 수 없습니다.
say.prototype .func2=function(){alert(" func2," this.f);}
say.func1()
(new say()).func2()
say.func2() ; //오류, 프로토타입 함수에 정의됨,
say.func3()을 호출하기 전에 객체를 인스턴스화해야 함; //오류,
(new say())를 호출하기 전에 클래스에 정의된 함수를 인스턴스화해야 함 .func3();
var obj={
fld1:10,
func1:function(msg){alert(msg);},
func4:function(){alert(this.fld1 );}
}
obj.prototype.func=function(){alert("func");}; //인스턴스 객체에서 객체를 정의하는 데 오류 프로토타입을 사용할 수 없습니다.
obj.func2=function (){alert("func2," this .fld1);}; //좋습니다. 인스턴스에 직접 정의된 함수는 이를 사용하여 객체
alert(obj.fld1)
obj의 속성에 액세스할 수 있습니다. .func1("func1");
obj .func2()
obj.func4();
Javascript 사용법 요약
http://www.jb51.net/article/16863.htm

JavaScript에 대한 심층적인 이해
http://www.jb51.net/article/19425.htm

객체 지향에 대한 자세한 설명은 JAVASCRIPT
http://www.jb51.net/article/17584.htm

이 포인터를 자바스크립트로 사용하세요
http://www.jb51.net/article/19434.htm

자바스크립트에서 이 키워드를 사용하는 방법에 대한 자세한 설명
http://www.jb51.net/article/7954.htm

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿