JAvascriptノート:javascriptのオブジェクトの作成(上)続編を深く分析する

13978 ワード

今日帰ってきて私のブログを見てみると、こんなに多くの人が推薦してくれて嬉しいです.皆さんは私の研究を認めてくれたようです.ブログを書く原動力はますます大きくなりました.そして、javascriptを書くのはブログ園で人気があることに気づきました.javaを書く視聴者は少なくなったようです.ブログ園でjavaを書くプログラマーは少ないかもしれません.Javascriptを使う人が多すぎるのかもしれませんが、javascriptを書く文章はやはり大衆化していて、後でjavascriptを書くことが多くなりました.
この文章は「javascriptのオブジェクトの作成を深く分析する」の下編ではなく、私が前編で書き間違えたところや、子供靴が分からないところについて解答します.
まず、次の子供靴のメッセージです.
     .  //         2    .
window.sayHello();// //id:102@!@name:InnerObj0@!@teststring:Test InnerObj0 //id:007@!@name:My Name is obj7@!@teststring:Test Obj7..

前編では、この例を書く目的は、「どこから直接関数を呼び出しても、中のthisはグローバルを指す」運用を深めることですので、関数内部の方法を書いて検証し、この原理をよく覚えておいてほしいと思いますが、実はjavascript原理で説明できるのです.
私がこの問題を考え始めたとき、この発生の原因はfunctionの定義の仕方が違うからではないかと思った(この考えはとても興奮して、私の前に「JAvascriptノート:javascriptの異なるfunction定義の違い」という博文があったが、実はこの文章の中で議論した問題は今までまだ少しシミュレーションがあったが、その原因はやはり良い実例コードがこの問題を説明していないからだ).コードを変更したら
//         2
function OuterObj(id1,name1,teststring1)
{
	this.id = id1;
	this.name = name1;
	this.teststring = teststring1;
	this.sayHello = function()
	{
		console.log('id:' + this.id + '@!@name:' + this.name + '@!@teststring:' + this.teststring);
	}
	var InnerObj = function(id2,name2,teststring2)
	{
		this.id = id2;
		this.name = name2;
		this.teststring = teststring2;
		this.sayHello = function()
		{
			 console.log('id:' + this.id + '@!@name:' + this.name + '@!@teststring:' + this.teststring);
		}
	}
	
	var innerVal = new InnerObj('101','InnerObj','Test InnerObj');
	console.log(innerVal instanceof InnerObj);//true
	innerVal.sayHello();//id:101@!@name:InnerObj@!@teststring:Test InnerObj
	InnerObj('102','InnerObj0','Test InnerObj0');
}

var outObj = new OuterObj('007','My Name is obj7','Test Obj7');
outObj.sayHello();//id:007@!@name:My Name is obj7@!@teststring:Test Obj7
sayHello();//id:102@!@name:InnerObj0@!@teststring:Test InnerObj0
window.sayHello();//id:102@!@name:InnerObj0@!@teststring:Test InnerObj0
console.log(id);//102
console.log(name);//InnerObj0
console.log(teststring);//Test InnerObj0

結果は同じで、ああ、本当に少しがっかりしました.しかし、振り返ってみると、「どこから直接関数を呼び出しても、中のthisはグローバルを指している」という言葉は、この言葉の意味をさらに理解しているようだ.前編のブログで「javascriptはオブジェクト向けのプログラミングができるので、プロセス向けの言語としては使えない」と述べていたのを覚えていますが、javascriptの設計者がこの言語を設計する際に2つの関数の実行方式(私が勝手に定義した構造関数式と関数式)を空で作ったわけではないと思います.理由は簡単です.何の本も書いていないので、私が長年開発した経験から、優秀なプログラマーたちが、理由もなく2つの解析器を作ることはできないと感じています.両者はきっと関係があります.関係はどこですか.答えはwindowです.
以下は私の分析です:みんなはすべてページがjavascript(ブラウザがjavascriptを支持する意味)を埋め込んでいることを知っていて、javascript解析器は自動的にwindowオブジェクトを構築して、この道理はこのように理解することができて、ブラウザのjavascript解析器の中でとっくにwindowクラスを書いて、ページがwindowオブジェクトをロードするとnewされて、簡単なプログラマーの開発のために、このwindowオブジェクトは一般的に省略できますが、確かに私たちのページに存在します.さらにjavascriptには、非常に遅いバインド、すなわちjavascriptオブジェクトがインスタンス化された後、オブジェクトのメソッドと属性を任意に定義できるという特徴があります.
では、javascriptにはnewによってインスタンスオブジェクトが生成されています.windowも例外ではありません.また、メソッドの呼び出しは[某某オブジェクト].[メソッド]のフォーマットです.私たちは普段、scriptラベルにfunctionメソッドを直接書いて、直接呼び出します.実は、極めて遅いバインドによってwindowオブジェクトに新しいメソッドを定義します.javascriptにはオブジェクトに属さないfunctionはありません.javascriptがメソッドが呼び出されたことを発見したとき、そのメソッドのオブジェクトが見つからないと、javascriptは自動的にwindowという福祉院に捨てられます.
ははは、この理解は完璧なようで、正しいかどうか分かりませんが、エビの人によろしくお願いします.
また、ある子供靴は私の前のブログの中の間違いを指摘しました.ああ、大勢の人が恥ずかしいので、今日徹夜してブログを書いて直しましょう.この子供靴の伝言は以下の通りです.
@     
// 1 sayHello() window.sayHello() ,
id:004@!@name:My Name is obj4@!@teststring:Test Obj4

windows (id,name,teststring), sayHello this windows , undefined...

, InnerObj('102','InnerObj0','Test InnerObj0');
: function,this window, .
, windows, window.sayHello() (window) ...
007 outObj .

前編の博文は天にまたがって書いて、翌日私の前日書いた実例に対して真剣に体得していないで、実は構造関数1のソースコードを深く分析します:
function Obj(id,name,teststring)
{
id = id;
name = name;
teststring = teststring;
sayHello = function(){
console.log('id:' + this.id + '@!@name:' + this.name + '@!@teststring:' + this.teststring);
}
}
var obj = new Obj('004','My Name is obj4','Test Obj4');
sayHello();//id:undefined@!@name:@!@teststring:undefined
window.sayHello();//id:undefined@!@name:@!@teststring:undefined
obj.sayHello();//obj.sayHello is not a function [ ] obj.sayHello();

その結果、idとteststringはundefinedであり、nameは空の値である.その时、この方法を书く时、结果は私の初志に反応していませんでしたが、その时は深く分析していないで休んで、翌日急いで书く时、ぼんやりした记忆に基づいて、変数の命名は明确に缲り返さないでくださいと思って、このようにもっとよく自分のテーマを话すことができて、确かに低级の间违いを犯しました.次はこの原始的な書き方について深く分析します.
上のコードの問題はid、nameとteststringがいったいその役割ドメインの下で定義されているのか、javascriptには変数を定義するキーワードvarがあるが、javascriptは同時にvar定義をしていない変数を正確に解析することができ、変数自体の役割ドメインにその変数のvar定義が見つかれば、JAvascript解析器は、その変数が見つかったvar定義を常に上位の役割ドメインに検索しますが、window役割ドメインの下にvar定義がない場合、javascript解析器は自動的にこの変数をwindowオブジェクトに付与します.次のコードを見て、プログラムを前のブログと同じように変更し、window.idなどのプロパティを印刷します.
function Obj(id1,name1,teststring1)
{
id = id1;
name = name1;
teststring = teststring1;
sayHello = function(){
console.log('id:' + this.id + '@!@name:' + this.name + '@!@teststring:' + this.teststring);
}
}
var obj = new Obj('004','My Name is obj4','Test Obj4');
console.log(window.id);
console.log(window.name);
console.log(window.teststring);
sayHello();//id:004@!@name:My Name is obj4@!@teststring:Test Obj4
window.sayHello();//id:004@!@name:My Name is obj4@!@teststring:Test Obj4
obj.sayHello();//obj.sayHello is not a function [ ] obj.sayHello();

その結果、その子供靴が指摘したように、thisの属性も方法もwindowに属していないことに気づいた.
疑問ですが、なぜfunction Obj(id,name,teststring)定義の結果、idとteststringがundefinedとなり、nameが空の値になるのでしょうか.上の分析で直感的に理解すれば、id、name、teststringはwindowではなくObjオブジェクトに属しているということですが、id、name、teststring自体は値がありますが、結果はなぜそれぞれ異なるのでしょうか.
function Obj(id,name,teststring)
{
console.log(window.id);//undefined
console.log(window.name);//(an empty string)
console.log(window.teststring);//undefined
id = id;
name = name;
teststring = teststring;
sayHello = function(){
console.log('id:' + this.id + '@!@name:' + this.name + '@!@teststring:' + this.teststring);
}
}
console.log(window.id);//undefined
console.log(window.name);//(an empty string)
console.log(window.teststring);//undefined
var obj = new Obj('004','My Name is obj4','Test Obj4');
sayHello();//id:undefined@!@name:@!@teststring:undefined
window.sayHello();//id:undefined@!@name:@!@teststring:undefined
obj.sayHello();//obj.sayHello is not a function [ ] obj.sayHello();

その結果、windowではid、name、teststringは確かに定義されていません.私がテストしたページはこのfunctionしかありません.id、name、teststringはObjの内部に定義される可能性があります.例えば、私は次のテストをしました.
function Obj(id,name,teststring)
{
id = id;
name = name;
teststring = teststring;

console.log(window.id);//undefined
console.log(window.name);//(an empty string)
console.log(window.teststring);//undefined

console.log(id);//004
console.log(name);//My Name is obj4
console.log(teststring);//Test Obj4

sayHello = function(){
console.log('id:' + this.id + '@!@name:' + this.name + '@!@teststring:' + this.teststring);
}
}
var obj = new Obj('004','My Name is obj4','Test Obj4');
sayHello();//id:undefined@!@name:@!@teststring:undefined
window.sayHello();//id:undefined@!@name:@!@teststring:undefined
obj.sayHello();//obj.sayHello is not a function [ ] obj.sayHello(

id、name、teststringの確定義はObjの内部にあるようですが、なぜthis.id、this.name、this.teststringがwindowの下のid、name、teststringの結果を印刷したのですか?
この解釈は簡単です.thisポインタはjavascriptの中でこの属性と方法を呼び出すオブジェクトを指しているので、sayHelloはwindowに属しています.自然にthisはwindowの下のid、name、teststringを指しています.
この中にはもう一つの難病があります.なぜidとteststringはundefinedで、そんなに空の対象ですか.
次のテストを行いました.
function TestObj()
{
console.log(teststring);//teststring is not defined
}

var testobj = new TestObj();

次はidです.
function TestObj()
{
console.log(id);//id is not defined
}

var testobj = new TestObj();

最後に来たのはnameです.
function TestObj()
{
console.log(name);//(an empty string)
}

var testobj = new TestObj();

id、name、teststringをカスタムfunctionに入れずにwindowの下に直接書くのも同様の結果であり、javascript自体のオブジェクトにname属性が定義されているため、nameの値は空であり、その他は未定義であることを示しています.
私は今自分が研究をしていると位置づけているので、私はいつも自分に厳格さを要求しています.自分には不注意な欠点がありますが.私がブログを書くのも文会友で、みんながもっと交流してアドバイスをして、みんなが一緒に進歩したことを望んでいます.