この記事では、JavaScript のオブジェクト指向の概念を解析する際の参照型とスコープを主に紹介し、関数の操作範囲を拡張するために必要な呼び出しメソッドと適用メソッドに焦点を当てます。
参照型
。参照型には主に、オブジェクト型、配列型、日付型、正規表現型、関数型などが含まれます。
参照型を使用する場合、参照型からオブジェクト(インスタンス)を生成する必要があります。つまり、参照型はテンプレートに相当します。ある参照型を使用する場合、このテンプレートを使用してオブジェクトを生成する必要があるため、参照型はオブジェクト定義と呼ばれることもあります。
たとえば、誰かの個人情報と行動を定義するために人物オブジェクトを生成する必要がある場合、オブジェクト タイプに依存する必要があります:
var person = new Object(); person.name = "jiangshui"; person.sayName = function(){ console.log(this.name); }
上記の人物オブジェクトは、 new 演算子 " を通じてオブジェクト タイプを使用します。テンプレート」の定義。次に、属性名とメソッドsayNameをこのオブジェクトに追加できます。プロパティとメソッドは Object 型の「機能」であるため、Object などの参照型を通じて作成されたオブジェクトはこれを使用できます。
オブジェクトの作成には必ずしも new 演算子を使用する必要はありません。たとえば、上記のように Object タイプのオブジェクトを作成するには、次の 2 つのメソッドを使用することもできます。
var person = {}; person.name = "jiangshui"; person.sayName = function(){ console.log(this.name); }
または
var person = { name : "jiangshui", sayName : function(){ console.log(this.name); } };
{} 演算子は new Object() と同じ機能を持ち、操作を簡素化します。上記 2 つの書き方にはいくつかの違いがあります。1 つ目は「追加」です。つまり、同じ名前の属性メソッドが既に存在する場合は、それを上書きします。 2 番目のタイプは「置換」です。これは、人物オブジェクトの属性とメソッドが以前に定義されているかどうかに関係なく、このメソッドは以前に定義されたものを新しく定義された内容に完全に置き換えることを意味します。参照型で生成されたオブジェクトはメモリ上の領域に格納され、そのポインタは変数 (person) に保存されるため、2 番目の書き方は、新しいオブジェクト (新しいメモリ領域) を生成し、そのオブジェクトを保存することです。 person 変数 新しいメモリ領域を指すため、以前のメモリ領域が置き換えられます。これを理解することは、後で理解するために非常に重要です。
配列型などの他の参照型の使用法もほぼ同じです。[] を使用してオブジェクトを生成したり、オブジェクトを直接定義したりすることもできます。配列オブジェクトが生成されると、情報コンテンツを配列形式で保存できます。また、オブジェクトは、プッシュ、シフト、ソートなどの配列型で定義されたメソッドを取得し、これらのメソッドを呼び出すことができます。 、例:
var colors = []; colors.push('red','green'); console.log(colors);
上記のコードは、Array 型を通じて配列型オブジェクトを作成し、Array 型で前に定義した Push メソッドを呼び出し、オブジェクトに赤と緑の値を追加します。 、最後にコンソールに出力すると確認できます。
メソッドの呼び出しと適用これら 2 つのメソッドは Function タイプによって提供されます。つまり、関数で使用できます。 call メソッドと apply メソッドは同じ機能を持ちます。つまり、関数の操作範囲を拡張できます。違いは、call を使用する場合、関数に渡されるパラメーターを 1 つずつリストする必要があるのに対し、apply メソッドはその必要がないことです。このようにして、独自の機能の要件に応じて呼び出しを使用するか適用するかを決定できます。
関数が実行されるスコープを拡張するとはどういう意味ですか?例を挙げれば理解できるでしょう。
このように理解できます。関数はコンテナー (スコープ) にラップされており、このコンテナーにはいくつかの変数やその他のものがあります。関数が実行されるとき、これらの変数を呼び出すときなどに、このものが検索されます。現在のコンテナ。このコンテナは、実際には、より大きなコンテナ内にラップされています。現在の小さなコンテナが存在しない場合、関数は、最大のコンテナ ウィンドウ オブジェクトが見つかるまで、より大きなコンテナ内でそれを検索します。ただし、関数が現在の小さなコンテナーで実行されており、対応する変数が小さなコンテナーにある場合、それらが大きなコンテナーにある場合でも、関数は独自のコンテナー内の変数を呼び出します。
call メソッドと apply メソッドは、この問題を解決し、コンテナーの制限を突破するためのものです。先ほどの例では、
var person = { name : "jiangshui", sayName : function(){ console.log(this.name); } };
Chromeのコンソールを開いて貼り付けて実行し、person.sayName()を実行すると
このとき、personは作成されたコンテナ SayName メソッド (関数) は、実行時に person スコープで実行される必要があります。最下部で直接実行した場合、つまり window のスコープで実行した場合、sayName メソッドが window の下で定義されていないため、未定義エラーが報告されます。内部の this ポインターは特別なもので、現在のスコープを指します。this.name の意味は、現在のスコープの下で名前の値を呼び出すことです。
次に、ウィンドウ オブジェクトに name 属性を追加します:
window.name = "yujiangshui";
、または直接
name = "yujiangshui";
因为 window 是最大的容器,所以 window 可以省略掉,所有定义的属性或者变量,都挂靠到 window 上面去了,不信可以看:
那现在我们就想在 window 这个大容器下面,运行 person 小容器里面的 sayName 方法,就需要用 call 或 apply 来扩充 sayName 方法的作用域。执行下面语句:
person.sayName.call(window);
或者
person.sayName.call(this);
输出的结果都是一样的,你也可以换用 apply 看看效果,因为这个 demo 太简单的,不需要传递参数,所以 call 和 apply 功能效果就完全一致了。
解释一下上面代码,sayName 首先是 Function 类型的实例,也就具有了 call 方法和 apply 方法,call 和 apply 方法既然是 Function 类型的方法,所以就需要用这种方式调用 person.sayName.call(window) 而不是什么 person.sayName().call(window) 之类的。
然后 call 和 apply 方法的参数,就是一个作用域(对象),表示将前面的函数在传递进去的作用域下面运行。将 window 这对象传递进去之后,sayName 方法中的 this.name 指向的就是 window.name,于是就扩充了作用域。
为什么传递 window 和 this 都是一样的效果?因为我们当前执行这个函数的位置是 window,前面说过 this 指针指向的是当前作用域,所以 this 指向的就是 window,所以就等于 window。
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
设计模式中的组合模式在JavaScript程序构建中的使用(高级篇)
详细解读JavaScript设计模式开发中的桥接模式(高级篇)
以上がJavaScript オブジェクト指向の概念におけるオブジェクトのタイプとスコープの包括的な分析 (例付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。