JavaScript OOP(三)
17078 ワード
オブジェクト引継ぎ
Aオブジェクトは、Bオブジェクトを継承することにより、Bオブジェクトの属性と方法のすべてを直接所有することができます.これ
コードの多重化には非常に有用である.
JavaScript言語の継承はクラスではなく、プロトタイプの文法飴に過ぎません.
璣萼33852;伝统の原型のチェーン式は継承します.
-継承属性が多すぎます.
-例えば一つの関数がプロトタイプの方法や属性を使わないと、方法や属性が過剰になります.
function Grand(){};
Grand.prototype.name="grand";
let grand = new Grand();
Father.prototype=grand;
function Father(){}
let father = new Father();
Son.prototype=father;
function Son(){}
let son = new Son();
葃菟菗33751;借用構造関数使用call/apply
-本当に継承されていないので、プロトタイプのメソッドを呼び出すことはできません.また、呼び出しごとに複数回の関数を呼び出します.実際の手順は少なくなりません.
-工業級推奨使用
-欠点はプライベートプロトタイプを追加できませんでした.
function Father() { }
function Son() {
Father.call(this); //
}
Son.prototype.print = function() {
Father.prototype.print.call(this);//
}
//
Son.prototype = Object.create(Father.prototype);
Son.prototype.constructor = Son;
シシシシシシシ圣杯模式
>隠蔽的に付加されたものは私有化され、公共に定義されたものは取り出して公有化される.
let inherit =(function(){
let Interim =function Interim() {};
return function (Target,Origin){//
Interim.prototype =Object.create(Origin);
Target.prototype = Interim.prototype;
// , constuctor ,
Target.prototype.constuctor = Target;
Target.prototype.yliluokka =Origin;
}
}())
璣菗33751;多重継承
JavaScriptは複数の継承機能を提供しません.つまり、一つのオブジェクトが同時に複数のオブジェクトを継承することができません.しかし、この機能はObject.assign`を通じて実現できます.このパターンをMixin(混入)と呼びます.
function Fn1(){ }
function Fn2(){ }
function Son(){
F1.call(this);
F2.call(this);
}
// F1
Son.prototype =Object.create(Fn1.prototype);
// F2
Object.assign(Son.prototype,Fn2.prototype);
Son.prototype.constructor =Son;
let a =new Son();
璣璖菚cal,appy and bind difference
を選択します. 関数内部のthisの指向(すなわち関数実行時の作用領域)を変更し、指定された作用領域で関数を呼び出します.
璣璖29846;33751;cal and appy
function test() {}
//test() == test.call()
let obj ={};
Object.prototype.toString.call(obj) //"[object Object]"
// call apply this
// obj.toString()
`call and appy`の違いは、伝来にあります.-call 2番目のパラメータから単一のパラメータを転送します.
-apply 2番目のパラメータは配列またはクラス配列です.
//
let a = [1, 2, 4, 1, 15];
Math.max.apply(null, a) // 15
// undefined
Array.apply(null [1,,3,,4)//[1,undefined,3,undefined,4];
空の要素とundefinedの違い
-forEachメソッドは空の要素をスキップしますが、undefinedはスキップされません.したがって、内部要素を遍歴すると、異なる結果が得られます.
類似配列のオブジェクトを変換
let obj={0: 1, length: 2}
Array.protetype.slice.apply(obj);//[1,undefined]
処理されるオブジェクトには、length属性と対応する数字キーが必要です.パラメータが空、null、undefinedであれば、デフォルトはグローバルオブジェクトに入ります.
#### ビッド
bind法は、関数内のthisをあるオブジェクトに結合し、新しい関数を返します.
let counter = {
count: 0,
inc: function () {
this.count++;
}
};
let func = counter.inc.bind(counter);
func();
counter.count // 1
let add = function (x, y) {
return x * this.m + y * this.n;
}
let obj = {
m: 2,
n: 2
};
let newAdd = add.bind(obj, 5); // x 5
newAdd(5) // 20
newAdd(1,5)//12
最初のパラメータはnullまたはundefinedで、thisをグローバルオブジェクトに結びつけるのと同じです.璣璖33751;bind方法使用上の注意点
-bindメソッドを実行するたびに、新しい関数を返します.変数の受信が必要です.
-コールバック関数と結合して使用します.
let counter = {
count: 0,
inc: function () {
'use strict';
this.count++;
}
};
function callIt(callback) {
callback();
}
callIt(counter.inc.bind(counter));
counter.count // 1
-コール方法と組み合わせて使う
[1, 2, 3].slice(0, 1) // [1]
//
Array.prototype.slice.call([1, 2, 3], 0, 1) // [1]
// Array.prototype.slice Function.prototype.call
// Array.prototype.slice.call。
let slice = Function.prototype.call.bind(Array.prototype.slice);
Function.prototype.slice.call([1, 2, 3], 0, 1) // [1]
//slice([1, 2, 3], 0, 1)
let push = Function.prototype.call.bind(Array.prototype.push);
let pop = Function.prototype.call.bind(Array.prototype.pop);
let a = [1 ,2 ,3];
push(a, 4)
a // [1, 2, 3, 4]
pop(a)
a // [1, 2, 3]
-Function.prototype.bind方法をFuntions.prototype.callにする方法は、bindの呼び出し形式も書き換えられます.
function f() {
console.log(this.v);
}
let o = { v: 123 };
let bind = Function.prototype.call.bind(Function.prototype.bind);
bind(f, o)() // 123
璣菗`Objectシステムのデフォルトの方法`.
-`get ProttypeOf`オブジェクトの原型を取得するには、パラメータは一つしかありません.
function Foo (){}
let obj = new Foo ();
Object.getPrototypeOf(obj) // Foo.prototype
//
Object.getPrototypeOf({}) // Object.prototype
// Object.prototype
Object.getPrototypeOf(Object.prototype) //null
// Foo
Object.getPrototypeOf(Foo) // Function.prototype
-`set ProttotypeOf`オブジェクトの原型を設定します.
二つのパラメータがあります
1.既存のオブジェクト
2.継承された原型の対象
let now = {};
let pro = {name:"Owen"};
Object.setPrototypeOf(now,pro);
now.name //"Owen"
-`Object.creat()`
>インスタンスオブジェクトを生成するための一般的な方法パラメータは、オブジェクトまたはnullでなければなりません.
-パラメータが`null`の場合、属性や方法は一切引き継がれないオブジェクトが生成されます.
let obj = Object.create(null);
obj.toString()// Error
//
let obj = Object.create({}, {
p1: {
value: 123,
enumerable: true,
configurable: true,
writable: true,
},
p2: {
value: 'Owen',
enumerable: true,
configurable: true,
writable: true,
}
});
//
let obj = Object.create({});
obj.p1 = 123;
obj.p2 = 'Owen';
// 。
function Foo() {}
let f = new Foo();
let b = Object.create(f);
b.constructor === Foo // true
b instanceof Foo // true
-`object.isProttypeOf`.
>対象がパラメータオブジェクトの原型チェーン上にあるかどうかを判断します.
function F(){}
let f = new F()
F.prototype.isPrototypeOf(f) //true
-原型を得るための3つの方法
1.`obj._u uプロト.
2.`obj.com nstructor.prototype`.
3.`Object.get ProttypeOf(obj)`.
-前二種類は信頼できません.全部手作業で修正します.プロト.ブラウザだけが配置が必要です.
-`getOwn PropertyNames`と`keys`
>パラメータオブジェクトの属性名を配列形式で返します.
//
Object.getOwnPropertyNames(Date);//["length", "name", "prototype", "now", "parse", "UTC"]
//
Object.keys(Date)// []
-ハスOwnProperty`
>パラメータが自分の属性かどうかを判断し、プロトタイプチェーンを巡回しない唯一の方法
Array.hasOwnProperty('length')//true
ヽoo.ツ..........................................................
コピー対象は二つのことを確保する必要があります.
-元のオブジェクトと同じ原型を持っています.
-元のオブジェクトと同じ実例的な属性を持つ.
function copyOwn (target,origin){
Object.getOwnPropertyNames(origin).forEach((key)=>{
let desc =Object.getOwnPropertyDescriptor(origin,key);
Object.defineProperty(target,origin,desc);
})
return target
}
function copy(origin){
let clone = Object.create (Object.getPrototypeOf(origin));
copyOwn(clone,origin)
return clone
}
//es8
const copyTwo = origin =>Object.create( Object.getPropertyOf(origin),Object.getOwnPropertyDescriptor(origin) );
oop(一)