クラスとオブジェクトの概念
1) オブジェクト指向?
オブジェクト指向は一種のプログラミングの考え方であり、クラスとオブジェクトという 2 つの非常に重要な概念があります。
クラス: これは抽象的なものであり、具体的ではありません。カテゴリは、同じ特性を持つもののクラスです。JS には多くのクラスがあり、自分でクラスを定義することもできます。
オブジェクト: オブジェクトは具体的なクラスを通じて作成されます。JSにはオブジェクトもたくさんあり、自分でオブジェクトを作成することもできます。
2) オブジェクト?
オブジェクトには多くの静的な特徴があり、それらは通常変数によって記述され、現時点では変数は属性とも呼ばれます。
オブジェクトには多くの動的な機能があり、それらは通常、メソッド (属性) とも呼ばれる関数によって記述されます。
オブジェクトは、順序付けされていないプロパティのコレクション (操作のコレクション (CRUD)) です。
3)クラスは?
Number、String、Boolean、Object、Math、Date など、多くのクラスが JS で提供されています。
次のように、new 演算子を使用してクラスを通じてオブジェクトを作成します。 let d = new Date();
新しいクラスはオブジェクトを作成できます。
4) 3 つの法則、2 つの連鎖:
法則 1: すべてはオブジェクトである (配列、関数、オブジェクト、および基本データ型も、特定の状況ではオブジェクトになります)
法則 2: すべてのオブジェクトはクラスを通じて作成されます (場合によっては関数もクラスになります)
法則 3: オブジェクトは順序付けされていない属性のコレクション (操作 (CRUD) コレクション)
2 つのチェーン: スコープ チェーンとプロトタイプ チェーン。
5) オブジェクトは、順序付けされていない属性のコレクションです (オブジェクト内の追加、削除、変更、およびクエリ)。
----オブジェクトを作成する 2 つの方法: リテラル、新規
トイレ = { にします
名前:「王彩」、
年齢:100歳、
言う:関数(){
console.log("ワンワン...")}}
-----オブジェクト内のプロパティにアクセスします。オブジェクト内のプロパティにアクセスするには、ドット演算子、[""] 構文を使用します。
!特殊な場合に注意してください: プロパティ名が変数の場合: オブジェクト内のプロパティを取得する方法は 1 つだけです: [] の中に引用符が含まれていないことに注意してください。
!オブジェクトに属性を追加します。ドット演算子を使用し、[""] 構文を使用してオブジェクト内の属性にアクセスします。同名の属性を追加した場合、同名の属性は上書きされるので注意してください。
!オブジェクトのプロパティを設定します(詳細設定): 構成: 削除するかどうか; 書き込み可能: プロパティ値を変更できるかどうか; enumerable: 列挙できるかどうか; value: プロパティ値を示します、プロパティ値は指定されていません、デフォルト値は: 未定義; 注: オブジェクトにそのようなプロパティがない場合、微調整はこの新しいプロパティの追加に属します。
!オブジェクトからプロパティを削除する
delect オブジェクト名、属性名 (オブジェクト内の特定の属性を削除); デフォルトでは、オブジェクト内の属性は変更可能です、列挙: 属性をトラバースするために for in を使用します
属性を削除する特別な例: a と b はグローバル変数であり、グローバル変数はウィンドウ属性として使用されます。
var a = 110;
b = 666;
delete a; // ウィンドウオブジェクトの a 属性を削除します
delete b; // ウィンドウオブジェクトの b 属性を削除します
console.log(a) // 110a は削除されていません
console.log(b) // ReferenceError: b が定義されていません b は削除されました
注: var を含むグローバル変数は削除できませんが、var を持たないグローバル変数は削除できます。
注: var を使用する場合、window オブジェクトの a 属性に configurable: false を設定するのと同じです。
!列挙オブジェクトのプロパティ
列挙オブジェクトのプロパティの例を見てみましょう: for 。。で
for(トイレのアイテム){
コンソール.ログ(項目)
}
オブジェクトのプロパティを列挙する例を挙げてください。 Object.keys(オブジェクト名): オブジェクトのプロパティを走査しても、値は見つかりません。値は自分自身の内部でしか見つかりません。また、列挙不可能なプロパティを走査することはできません。
console.log(Object.keys(wc)) // ["名前", "年齢", "言う"]
value: 直接変更または取得できます。
ちょっとした知識を広めましょう: 配列はキーと値のペアとして理解できます。
let arr = ["a","b","c"]
{0:"a",1:"b",2:"c"}
for(var i=0; i<arr.length; i++){
コンソール.ログ(arr[i]) }
次に、オブジェクトのプロパティを微調整する方法について説明します。
1) Object.defineproperty(ObjectName, "PropertyName", {構成テーブル})
2) Object.defineproperty は、オブジェクトの新しいプロパティを直接定義するか、オブジェクトの既存のプロパティを変更して、このオブジェクトを返します。
3) オブジェクトはクラス class. xxx は xxx がクラスの属性 (静的属性) であることを示します
4) defineproperty はオブジェクトクラスの静的プロパティです。define は定義プロパティを意味します。
!!設定時に属性名を引用符で囲む必要があることに注意してください。そうしないとエラーが報告されます。ユーザーは変数として扱われ、変数を調整して特性を設定することはできません。
!!属性変更の特性に注意してください。設定を削除できなくなると、その後は設定できなくなり、削除できるようになります。!
標準的な例を見てみましょう。
トイレ = { にします
名前:「王彩」、
年齢:100歳、
言う:関数(){
console.log("ワンワン...")}}
洗練された設定
Object.defineProperty(wc,"スコア",{
configurable: false, // wc オブジェクトのスコア属性は削除できません
値:100
});
WC.スコアを削除
console.log(wc.スコア)
たとえば、変更または削除できない定数を定義します。
obj = {} にします。
Object.defineProperty(obj,"PI",{
writeable: false、// 変更できません
構成可能: false、// 削除できません
値:3.14、
enumerable:true, // 列挙可能
})
コンソール.ログ(obj.PI)
(6) 属性がオブジェクトに属するかどうかを判断する
in 演算子: プロパティがオブジェクトに属しているかどうかを判断します。
hasOwnProperty:このメソッドは、オブジェクトの独自のプロパティに指定されたプロパティがあるかどうか (つまり、指定されたキーが存在するかどうか) を示すブール値を返します。
in と hasOwnProperty の違いは何ですか?
in は最初にそれ自体の内部でそれを探します。見つからない場合は、そのプロトタイプ オブジェクトでそれを探します。
hasOwnProperty はそれ自体内でのみ見つかります。
オペレーター:
トイレ = { にします
名前:「王彩」、
年齢:100歳、
言う:関数(){
console.log("ワンワン...")}}
//console.log("name" in wc) // キーを true 以外で使用する場合は引用符で囲む必要があります
//console.log(wc.hasOwnProperty("say")) //true どちらも本体のプロパティを取得できます
プロトタイプのメソッドを取得できます。
var arr = ["a","b","c"]
// arr はオブジェクトです。 Push は、arr 内で見つからないメソッド Push です。そのため、そのプロトタイプ オブジェクトに移動して見つけます。
arr.push("d")
console.log("push" in arr) // true
console.log(arr.hasOwnProperty("push")) // false
このナレッジ ポイントの配列の重複排除と統計配列内の要素の数は次のとおりです。
アレイの重複排除:
var arr = [1,2,3,3,1,2,4,5,2,4,5,7,5,7,8];
// 関数 fn(arr){
// var newArr = [];
// // 配列内の各要素が処理されたかどうかを判断します
// var o = {}; // {"1":true,"2":true,"3":true}
// for(var i=0; i<arr.length; i++){
// let t = arr[i]; // t は古い配列の各要素を表します
// if(o[t]){ }else{
// newArr.push(arr[i])
// o[t] = true;}}
// newArr を返します。}
// var newArr = fn(arr);
// console.log(newArr) // [1、2、3、4、5、7、8]
配列内の要素の数を数えます。
var arr = [1,2,3,3,1,2,4,2,6,2];
関数 fn(arr){
var obj = {};// {"1":2, "2":3, "3":100} {"1":1,"2":1}
for(var i=0; i<arr.length; i++){
var t = arr[i]
// obj[t] = 1 obj[t] = obj[t]+1
if(obj.hasOwnProperty(t)){
obj[t] = obj[t] + 1
}それ以外{
obj[t] = 1;}}
オブジェクトを返します;}
let res = fn(arr)
// res には、各要素が出現する回数が含まれている必要があります。 res はオブジェクトです
コンソールログ(解像度)
2 番目の関数 (js の VIP、ハイライト)
JS では関数が特殊です。
1) 以前に学習した関数を通常の関数として扱うだけです
2) JSでは関数はクラス(コンストラクタ)とみなすことができ、関数名(クラス名)の最初の文字は通常大文字で表記されます。
関数宣言(この関数は現時点では単なる普通の関数です)
関数 fn(a,b){
ローカル実行コンテキスト (ローカル スタック、関数スタックなど) を生成します。
仮パラメータの割り当て、宣言のプロモーション、コードの実行
a+b を返します。
}
// console.log(fn(1,2))
3) クラスの役割はオブジェクトを作成することです
function CreateDog(名前, 年齢){
this.name = 名前;
this.age = 年齢;}
let wc = new CreateDog("wangcai",100);
console.log(wc.name)
console.log(トイレ.年齢)
4) 機能の2つの役割
関数をクラス (コンストラクター) として扱います。
目的: オブジェクトを作成する
関数には次の 2 つの役割があります。
!通常の関数 --> ローカル実行コンテキスト
// 通常の関数として関数を呼び出す
// 関数 fn(a,b){
// a+b を返す
// }
// 関数の戻り値を呼び出すと、ローカル実行コンテキストが生成されます
// fn(1,2)
!クラス (コンストラクター、コンストラクター) ---> new; 関数をクラスとして扱うことと、関数を通常の関数として扱うことの違いは何ですか?
クラスとして new が必要ですが、 new と関数を直接呼び出すことの違いは何でしょうか?
1) new はコードの実行時にオブジェクトを作成し、2) 次に this がこのオブジェクトを指すようにし、3) 最後にオブジェクトのアドレスを返します。
// 通常、クラス名の最初の文字は大文字になります。
function CreateDog(名前,年齢){
this.name = 名前;
this.age = 年齢;}
let wc = new CreateDog("wangcai",1000);
console.log(wc.name)
console.log(トイレ.年齢)
知らせ:
1: 関数をクラスとして扱う
!Fn の最初の文字は大文字であり、必須ではありませんが、業界のデフォルトのルールです
!内部的にオブジェクトを作成し、何もしなくても戻ります。
!各クラスに this があり、作成されたオブジェクトを参照します。
!new は最終的にオブジェクトを取得する必要があります
注意: return の後のステートメントは実行されません。
関数をクラスとして扱う場合は、共通の基本データ型のデータを返します。これは、返さないことと同じです。
内部的にオブジェクトを返します
2: オブジェクトがクラスで返される場合:関数がクラスとみなされ、オブジェクトがクラスで返される場合、そのオブジェクトは最終的にデフォルトのオブジェクトを上書きします。
関数 Fn(){
this.name = "xxx";
戻る {
年齢:666}}
console.log(Fn()); // {年齢: 666}
r = 新しい Fn(); とします。
コンソール.ログ(r); // {年齢: 666}
5) 新しいオブジェクトはすべて独立しています:! !!!
// コードが CreateDog に対して実行されると、いくつかのことを行います。
// 仮パラメータの代入
// 宣言の促進
// コードの実行
// 空のオブジェクトを作成します
// これが空のオブジェクトを指すようにします
// このオブジェクトを返す
// let a = 666; // はローカル実行コンテキストのローカル変数です
// this.name = name // このオブジェクトに name 属性を追加し、値を割り当てます
// this.age = age // このオブジェクトに age 属性を追加して割り当てます
// this.say = function(){} // このオブジェクトにsay属性を追加して割り当てます
function CreateDog(名前, 年齢){
a = 666 とします。
this.name = 名前;
this.age = 年齢;
this.say = function(){
console.log("ワンワン...")}}
let wc = new CreateDog("wangcai",100);
console.log(wc.a) // 未定義
console.log(wc.name) // 王彩
// これは作成したオブジェクトを指します
let wc1 = new CreateDog("wc1",1);
let wc2 = new CreateDog("wc2",2);
console.log(wc1) // {名前: "wc1"、年齢: 1、言う: ƒ}
console.log(wc2) // {名前: "wc2"、年齢: 2、言う: ƒ}
console.log(wc1 === wc2) // false
// 新しい CreateDog はパラメータを渡すことができません
// クラスを新規作成する場合、() を追加することも追加しないこともできます。違いは、() を追加せずにパラメーターを渡すことができないことです。
wc3 = 新しい CreateDog を許可します。
console.log(wc3) // {名前: 未定義、年齢: 未定義、言う: ƒ}
instanceof は、オブジェクトがクラス (関数、コンストラクター) に属しているかどうかを決定します。
function CreateDog(名前, 年齢){
this.name = 名前;
this.age = 年齢;}
let wc = new CreateDog("wangcai",100);
// console.log(wc instanceof CreateDog) // true
6) JS にはデフォルトで多くのクラスがあります。
例:数値、文字列、ブール値、配列、オブジェクト、数学、日付、正規表現...
基本データ型も特定のクラスに属するオブジェクト(インスタンス)です
instanceof は基本データ型を検出できません。typeof は基本データ型を検出できますが、参照データ型の検出は不正確です。
instanceof と typeof の両方には、データ型の検出に関して欠点があります。
3 つの JSON: JavaScript オブジェクトの表記 JS オブジェクトの表記
// JSON が合法かどうかを確認します: http://www.bejson.com/
インターネット アクセスの本質: クライアント: 携帯電話、QQ、ブラウザ... サーバー: コンピューター, インターネット アクセスは、クライアントがサーバーに要求し、サーバーが必要なデータを返すプロセスです。
JSON は、クライアントとサーバー間の通信用のデータ形式です。
JSON は通常、次の 2 つの方法で記述されます。
配列の形式: [{},{},{}]
オブジェクトの形式: {}
1) JSON データの構文:
1. キーと値のコンポーネントがある 2. キーと値のペアはカンマで区切られる 3. オブジェクトを {} に入れて配列に入れる 4. キーも二重引用符で囲む必要がある
ここで、スチュ = [
{"id":1、"名前":"z3"、"年齢":4、"スコア":"10"},
{"id":2、"名前":"z4"、"年齢":5、"スコア":"11"},
{"id":3、"名前":"z5"、"年齢":6、"スコア":"12"}
]
var obj = {
名前:「王彩」、
年齢:100歳、
isSleep:true、
言う:関数(){
}}
2) JSON: JavaScript Object Notation JS オブジェクト表現
JSON は特別な JS オブジェクトであり、軽量のデータ交換形式です。
JSON の操作: CRUD 操作 (追加、削除、変更、クエリ)
ここで、スチュ = [
{"id":1、"名前":"z3"、"年齢":4、"スコア":"10"},
{"id":2、"名前":"z4"、"年齢":5、"スコア":"11"},
{"id":3、"名前":"z5"、"年齢":6、"スコア":"12"}
]
// 訪問
console.log(stu[0])
console.log(stu[0].name)
console.log(stu[0]["名前"])
// 改訂
stu[0].スコア = "100"
console.log(stu[0])
// 消去
この[0].スコアを削除します。
console.log(stu[0])
// トラバース
for(var i=0; i<stu.length; i++){
// console.log(stu[i])
for(stu[i] の var item){
console.log(stu[i].age)
}}
2) JSON オブジェクト、JSON 文字列
JSON には 2 つの形式があります。 JSON 文字列: 本質的には文字列であり、一重引用符でのみ囲むことができます。
JSON 文字列:本質的には文字列であり、一重引用符でのみ囲むことができます。
JSON オブジェクト:特別な JS オブジェクト
JSONオブジェクト
var obj = [{"id":"01","name":"王彩"}]
JSON文字列
var obj = '[{"id":"01","name":"wangcai"}]'
JSON文字列とJSONオブジェクトの間で変換する方法
JSONオブジェクトをJSON文字列に変換する
var obj = [{"id":"01","name":"王彩"}]
let str = window.JSON.stringify(obj)
コンソール.ログ(文字列)
console.log(文字列の種類)//文字列
JSON文字列をJSONオブジェクトに変換する
var obj = '[{"id":"01","name":"wangcai"}]'
let str = window.JSON.parse(obj)
コンソール.ログ(文字列)
console.log(typeof str)//オブジェクト
4 つのプロトタイプとプロトタイプ チェーン
プロパティタイプのプロトタイプ
1) プロトタイプ プロパティを持つ関数はありません (関数はオブジェクトでもあります)。プロトタイプは属性名であり、その属性値はオブジェクトであり、これをプロトタイプ オブジェクトと呼びます。
2) 多くのパブリック プロパティとメソッドがプロトタイプ オブジェクトに配置されます。
3) 各プロトタイプ オブジェクトにはコンストラクターと呼ばれる属性が必要です。構成要素は属性名でもあり、その属性値は現在の関数そのものです
4) 各オブジェクトには __proto__ という属性があり、これは属性名でもあり、プロトタイプ オブジェクトを指します。
Func はクラス (コンストラクター) であり、本質的には関数であり、関数はオブジェクトでもあります
すべての関数 (関数はオブジェクトでもあります) にはプロトタイプ プロパティがあります。
関数 Func(){
this.name = "xxx"
}
// obj1 の __proto__ は、obj1 オブジェクトを作成したクラスのプロトタイプ オブジェクトを指します。
obj1 = new Func(); とします。
obj2 = new Func(); とします。
Func.prototype.say = function(){
console.log("言う...")
}
オブジェクト内のプロパティにアクセスします。
オブジェクト内のプロパティにアクセスする
// console.log(obj1.name) // 内部に name 属性があるので、内部を探してください
// obj1.say() // 内部に Say メソッドがないので、プロトタイプ オブジェクト内で見つけてください
// obj2.say() // 内部に Say メソッドがないので、プロトタイプ オブジェクト内で見つけてください
オブジェクトはすべてのオブジェクトの最上位クラスであり、基本クラスとも呼ばれます。したがって、Object.prototype.__proto__ はそれ自体を指します。
それ自体を指すことは意味がないため、デフォルト値は null です。
プロトタイプチェーン: 属性を見つけたい場合は、まず自分の内部 (プライベート) でそれを探し、存在する場合はそれを使用し、後ろ向きに考えないでください。
そうでない場合は、__proto__ に従い、クラス プロトタイプ オブジェクトのプロパティを見つけ、Object.prototype が見つかるまで検索を続けます。
// テスト問題
console.log(obj1.say === obj2.say) // true
console.log(Func.prototype.say === obj1.say) // true
console.log(obj1.__proto__.say === Func.prototype.say) // true
console.log(obj1.__proto__ === Func.prototype) // true
console.log(obj1.name === obj2.name) // true
console.log(obj1 instanceof Func) /// true
console.log(obj1 オブジェクトのインスタンス) // true
プロトタイプとプロトタイプチェーン(jsの組み込みオブジェクトについて)
組み込みオブジェクトの配列 (コンストラクター)、arr をオブジェクトと呼びます。
var arr1 = 新しい配列("a","b","c")
var arr2 = 新しい配列("d","e","f")
console.log(Array.prototype === arr1.__proto__) // true
console.log(Array.prototype.push === arr1.push) // true
console.log(arr1 === arr2)//false
console.log(arr1 配列のインスタンス)//true
console.log(arr1 オブジェクトのインスタンス)//true
プロトタイプチェーン:
console.dir(arr1.__proto__)
console.dir(arr1.__proto__.__proto__)
console.dir(arr1.__proto__.__proto__.__proto__) // null
5: この質問
// ------------------ 状況 1: これはリスナー内のイベント ソースを表します
// ドム
var btn = document.getElementById("btn")
// btn はプレフィックスのイベント タイプでイベント ソースを呼び出します。
// function(){} イベント ハンドラ (リスナー)
btn.onclick = function(){
//alert(this) // [オブジェクト HTMLButtonElement]
console.log(これ)
//alert("ログインに成功しました...")
}
//---------------------- 状況 2: 非厳密モードでは、これは通常の関数で表示され、ウィンドウを示します。厳密モードでは、uneeeend を示します。
関数 f(){
console.log(this) // ウィンドウ }
f()
関数 f(){
「厳格に使用する」
console.log(this) // 未定義}
f()
// ------------------ 状況 3: これはオブジェクトのメソッドに表示され、現在のオブジェクトを示します
var obj = {
名前:「王彩」、
言う:関数(){
console.log(this) // {名前: "wangcai"、言う: ƒ}}}
obj.say();
// ------------------ 状況 4: これはクラス内に表示され、新しいオブジェクトを指していることを示します
関数 Func(){
this.name = "xxx";
console.log(this) // {名前: "xxx"} }
obj1 = new Func(); とします。
// ------------------ 状況 5: グローバル スコープでは、これはウィンドウを意味します
console.log(this) // ウィンドウ
注: メソッドの this ポイントは不明です。誰がメソッドを呼び出しても、それが誰であるかは不明です。
注: プライベート メソッドであってもパブリック メソッドであっても、メソッドを呼び出すのは誰です。
6: 無名関数について
無名関数を f に代入する
// var f = function(){}
g は関数名です。関数式の場合、関数名を指定できます。
// var f = function g(){console.log("はは...")}
// f()
// 関数式内の関数名で関数を呼び出すことはできません
// g() // g は定義されていません
g は関数名であり、関数本体で使用できます。この関数は g() を通じて呼び出すことができますが、終了がない場合は無限ループが発生します。g に基本データ型を割り当てても効果はありません。 g への参照データ型は効果がありません。
関数式の場合、関数名を持つことができます。関数の外部から関数名を使用して関数を呼び出すことはできません。関数名または関数呼び出しは関数内 (無限ループ) 内で使用できます。また、関数名の再割り当てはできません。
7: メソッドの呼び出し
-------------------------------------- についての予備的な理解呼び出しメソッド
1) call は関数のプロトタイプ オブジェクトのメソッドです。
2) 関数 .call、この関数を呼び出すことができます
3) f.call() のこれ f はウィンドウを意味します
4) f.call(obj) f のこれは obj を意味します
// 要求、obj 経由で f 関数を呼び出したいのですが、どうすればよいですか?
方法 1: 関数を obj の属性として使用する: この関数を obj の属性に掛けます。
// obj.f = f;
// obj.f(); // f....
方法 2: obj のプロパティを使用せず、使い終わったら削除する
// obj.f を削除します。
// console.log(obj) // {名前: "wangcai"}
方法 3: call を使用して obj に f メソッドを借用させます。f メソッド内のこれは obj を指します。
f.call(obj);
console.log(obj) // {名前: "王彩"}
----------------- JS では、この点を呼び出して変更できます。
call メソッド呼び出しの最初のパラメータについての深い理解 ------------------ 最初のパラメータ
// fn.call の目的は、fn を実行させ、fn の this のポイントを変更させることです。
// JS では、この点を呼び出すことで変更できます。
関数 fn(){
console.log(これ)
console.log("fn...")
}
// fn() この中の this はウィンドウを表します
// fn.call(); // fn のこれはウィンドウを意味します
// fn.call(123) // fn のこれは数値 {123} を意味します
// fn.call("hello") // fn のこれは String {"hello"} を意味します
// fn.call(true) // fn のこれはブール値 {true} を意味します
// fn.call({}) // {}
// obj = {name:"xxx"} にしておきます
// fn.call(obj) // {名前: "xxx"}
// ----------------- call メソッド呼び出しのその他のパラメーターについての深い理解
call メソッドはパラメータの受け渡しをサポートしており、call メソッドの 2 番目の実パラメータ以降は実パラメータのリストです。
let r = fn.call(obj,1,2)
コンソール.ログ(r)
// ----------------- call メソッド呼び出しの他のパラメーターについての深い理解 ------------------- ---
// 要約:
// 1) call は関数のプロトタイプ オブジェクトの属性です
// 2) 任意の関数を .call にできます。
// 3) 関数が呼び出されると、その関数が実行され、関数内の this は呼び出し内の最初の実パラメータを指します。
// 4) call メソッドに実際のパラメータがない場合、この関数も実行できますが、関数内でこれはウィンドウ (非厳密モード) を意味し、厳密モードでは未定義です
// 5) call の最初のパラメータが null の場合、非厳密モードでは、これは関数内でウィンドウを意味し、厳密モードでは null を意味します
// 6) 関数 .call() が実行されると、関数は必ず実行され、関数にパラメータを渡すことができます。呼び出しの 2 番目のパラメータから始まる実際のパラメータがこの関数に渡されます。
//手書き呼び出しの原理についてはここでは説明しません。
8: applyメソッド
apply と call の唯一の違いは、渡すパラメータの違いです。call はパラメータを 1 つずつ渡すこと、apply はパラメータを配列の形式で渡すことです。applyメソッドの原理についてはここでは書きません。
関数 fn(a, b){
コンソール.ログ(これ);
a+b を返します。
}
var obj = {名前:"xxx"}
// fn.call(obj,11,22)
let res = fn.apply(obj,[11,22])
コンソールログ(解像度)
9: バインドメソッド
1) call/apply と同様に、関数内で変更できます。
2) call/apply とは異なり、bind では前の関数を実行できません。手動で電話をかける必要があります。
// ----------------- バインド アプリケーション シナリオ
<button id="btn">login</button>// btn はイベント ソースを呼び出します。 click はイベント タイプを呼び出します。 function(){} はリスナーを呼び出します。
var btn = document.getElementById("btn");
// btn.onclick = function(){// クリック イベントを登録する
// console.log("....")
// }
JS はシングルスレッドであり、一度に 1 つのタスクしか実行できません。最初に同期タスクを実行し、次に非同期タスクが発生すると非同期タスクを実行します。
// console.log("開始")
// 関数 fn(){
// console.log("666")
// }
// // イベントは非同期タスクです
// btn.onclick = fn;
// console.log("終了")
// 関数 fn(){
// console.log(this)
// }
// btn.onclick = fn;
// 要件: リスナー内の this がイベント ソースを表すのではなく、obj を表すようにしたい
// var obj = {名前:"xxx"}
// 関数 fn(){
// console.log(this)
// }
// btn.onclick = fn.call(obj) // call はすぐに実行されるため、現時点では call を使用するのは適切ではありません
// // 要件: リスナー内の this がイベント ソースを表すのではなく、obj を表すようにしたい
// var obj = {名前:"xxx"}
// 関数 fn(){
// console.log(this)
// }
// btn.onclick = function(){
// fn.call(obj)
// }
要件: リスナー内の this がイベント ソースを表すのではなく、obj を表すようにしたい
var obj = {名前:"xxx"}
関数 fn(){
console.log(これ)
}
btn.onclick = fn.bind(obj);
バインドの原理についてはここでは説明しません
10: 属性がパブリック属性かどうかを判断する (インタビューの質問で述べられている)
面接の質問:
関数 fn1(){console.log(1)}
関数 fn2(){console.log(2)}
fn1.call(fn2); //1
fn1.call.call(fn2); //2
Function.prototype.call(fn1) //なし
Function.prototype.call.call(fn1) //1
11: 企業面接の質問で継承と原則について言及されている:
配列内の最大値と最小値を見つける 4 つの方法:
プロトタイプチェーンの継承に基づく:
継承の呼び出しまたは適用に基づいて、次のようにします。
構成の継承:
完全な継承:
メソッドをカプセル化して継承を実装します。
新しい原則の実装:
instanceof 原則の実装:
呼び出し原則:
原則を適用します:
バインド原則:
マイフラットの原則:
プッシュ原理:
// push的原理 Array.prototype.push = function(value){
// this[this.length] = 値;
// this.length++;
// this.length を返す;
// }