一符隙、實(shí)例方法(原型方法)
1、defineGetter
可以將一個(gè)函數(shù)綁定在當(dāng)前對象的指定屬性上垫毙,當(dāng)那個(gè)屬性的值被讀取時(shí)霹疫,你所綁定的函數(shù)就會(huì)被調(diào)用。
2综芥、defineSetter
可以將一個(gè)函數(shù)綁定在當(dāng)前對象的指定屬性上丽蝎,當(dāng)那個(gè)屬性被賦值時(shí),你所綁定的函數(shù)就會(huì)被調(diào)用膀藐。
3屠阻、lookupSetter
導(dǎo)出對應(yīng)的set方法红省。
4、lookupGetter
導(dǎo)出對應(yīng)get方法国觉。
class Person{
constructor(){
this.age = 18
}
}
//調(diào)用對應(yīng)的__defineGetter
let person = new Person()
//定義get 訪問對應(yīng)的屬性的時(shí)候調(diào)用的方法 屬性名 handler
person.__defineGetter__('age',function(){
console.log('getter調(diào)用了');
return '18'
})
console.log(person.age);
//定義對應(yīng)的set 用于設(shè)置的時(shí)候
person.__defineSetter__('username',function(value){
console.log('setter調(diào)用了 傳入的值'+value);
// this.username = value 循環(huán)調(diào)用問題 遞歸死循環(huán)
})
person.username = 'jack'
console.log(person);
//獲取對應(yīng)的get方法 指定的屬性
let get = person.__lookupGetter__('age')
let set = person.__lookupSetter__('username')
console.log(get);
console.log(set);
5吧恃、hasOwnProperty *
會(huì)返回一個(gè)布爾值,指示對象自身屬性中是否具有指定的屬性(也就是麻诀,是否有指定的鍵)
所有繼承了 [Object
] 的對象都會(huì)繼承到 hasOwnProperty
方法蚜枢。這個(gè)方法可以用來檢測一個(gè)對象是否含有特定的自身屬性;和 [in
]運(yùn)算符不同针饥,該方法會(huì)忽略掉那些從原型鏈上繼承到的屬性。
注意:即使屬性的值是 null
或 undefined
需频,只要屬性存在丁眼,hasOwnProperty
依舊會(huì)返回 true
。
class Person{
constructor(){
this.age = 18
}
}
Person.prototype.username = 'jack'
let person = new Person()
person.sex = '女'
//判斷對象上是否具備屬性 返回布爾類型
console.log(person.hasOwnProperty('age')); //true
console.log(person.hasOwnProperty('sex')); //true
console.log(person.hasOwnProperty('username')); //false
6昭殉、isPrototypeOf *
判斷當(dāng)前對象(構(gòu)造函數(shù)的原型對象)是否處在對應(yīng)參數(shù)對象的原型鏈上 返回布爾類型苞七。
class Son extends Person{
constructor(){
super()
}
}
//判斷當(dāng)前對象(構(gòu)造函數(shù))是否處在對應(yīng)參數(shù)對象的原型鏈上 返回布爾類型
console.log(Object.prototype.isPrototypeOf(person)); //true
let son = new Son()
console.log(Person.prototype.isPrototypeOf(son)); //true
7、propertyIsEnumerable
此方法可以確定對象中指定的屬性是否可以被 for...in循環(huán)枚舉挪丢,但是通過原型鏈繼承的屬性除外蹂风。如果對象沒有指定的屬性,則此方法返回
false`乾蓬。
// 返回boolean類型 屬性是否是可以枚舉(可以遍歷 for-in遍歷)
let obj = {
arr:[1,2,3],
o:{key:1},
v:123,
f:()=>{},
b:false
}
//判斷當(dāng)前屬性是否可以枚舉 可以遍歷
console.log(obj.propertyIsEnumerable('v')); //true
console.log(obj.propertyIsEnumerable('arr')); //true
console.log(obj.propertyIsEnumerable('o')); //true
console.log(obj.propertyIsEnumerable('f')); //true
console.log(obj.propertyIsEnumerable('b')); //true
8惠啄、valueOf
返回指定對象的原始值。
// valueOf提取對應(yīng)的值
console.log(new Object().valueOf());
9任内、toString和toLocaleString
toString()
方法返回一個(gè)表示該對象的字符串撵渡。
toLocaleString()
方法返回一個(gè)該對象的字符串表示。此方法被用于派生對象為了特定語言環(huán)境的目的(locale-specific purposes)而重載使用死嗦。
// toString 轉(zhuǎn)為字符串類型 引用類型出現(xiàn)的結(jié)果[object Object]
console.log(new Object().toString());
//toLocalString 轉(zhuǎn)為本地格式的字符串 千位分隔
console.log(Number(123456789).toLocaleString());
二趋距、實(shí)例屬性
1、__proto__
隱式原型
let obj = new Object()
console.log(obj.__proto__)
2越除、constructor
返回 [Object
] 的構(gòu)造函數(shù)(用于創(chuàng)建實(shí)例對象)节腐。注意,此屬性的值是對函數(shù)本身的引用摘盆,而不是一個(gè)包含函數(shù)名稱的字符串翼雀。
let obj = new Object()
console.log(obj.constructor) //指向?qū)?yīng)的構(gòu)造函數(shù)
三、靜態(tài)方法
1骡澈、assign*
assign 將后面的對象拷貝到第一個(gè)對象里面 返回的是一個(gè)新的對象 這個(gè)對象和原本第一個(gè)對象的地址一致(實(shí)現(xiàn)淺拷貝)
let target = {}
let obj = Object.assign(target,{name:'jack'},{age:18})
console.log(obj);
console.log(target);
注意:只會(huì)拷貝源對象 可枚舉的 和 自身的 屬性到目標(biāo)對象
2锅纺、create*
用于創(chuàng)建一個(gè)新對象,使用現(xiàn)有的對象來作為新創(chuàng)建對象的原型(prototype)肋殴。
//create 創(chuàng)建一個(gè)對象
let obj1 = {name:"張三"}
let obj2 = Object.create(obj1)
console.log(obj2); //將對應(yīng)obj1加到對應(yīng)的obj2的原型上
console.log(obj2 == obj1);
class Person{
constructor(){
this.name = 'tom'
}
}
let person = Object.create(Person) //根據(jù)傳入的對象的類型來創(chuàng)建對應(yīng)的對象
console.log(person); //函數(shù) Class本質(zhì)就是構(gòu)造函數(shù)
3囤锉、keys坦弟、values和entries*
- keys方法會(huì)返回一個(gè)由一個(gè)給定對象的自身可枚舉屬性組成的數(shù)組,數(shù)組中屬性名的排列順序和正常循環(huán)遍歷該對象時(shí)返回的順序一致官地。
- values方法返回一個(gè)給定對象自身的所有可枚舉屬性值的數(shù)組酿傍,值的順序與使用[
for...in
]循環(huán)的順序相同 ( 區(qū)別在于 for-in 循環(huán)枚舉原型鏈中的屬性 )。 - entries方法方法返回一個(gè)給定對象自身可枚舉屬性的鍵值對數(shù)組驱入,其排列與使用 [
for...in
]循環(huán)遍歷該對象時(shí)返回的順序一致(區(qū)別在于 for-in 循環(huán)還會(huì)枚舉原型鏈中的屬性)赤炒。
//keys values entries 返回的都是一個(gè)迭代器
let obj = {
name:'jack',
age:18,
sex:'男'
}
//獲取所有的key
let objKeys = Object.keys(obj) //返回所有key組成的偽數(shù)組
//獲取所有的value
let objValues = Object.values(obj) //返回所有key組成的偽數(shù)組
//獲取所有的鍵值對
let objEntries = Object.entries(obj) //返回所有key組成的偽數(shù)組
console.log(objKeys);
console.log(objValues);
console.log(objEntries);
//這三個(gè)獲取到的數(shù)組都可以進(jìn)行遍歷
objEntries.forEach(arr=>{
console.log(`key:${arr[0]} value : ${arr[1]}`);
})
4、is*
判斷兩個(gè)值是否為[同一個(gè)值]亏较,如果滿足以下任意條件則兩個(gè)值相等:
- 都是 [
undefined
] - 都是 [
null
] - 都是
true
或都是false
- 都是相同長度莺褒、相同字符、按相同順序排列的字符串
- 都是相同對象(意味著都是同一個(gè)對象的值引用)
- 都是數(shù)字且
- 都是
+0
- 都是
-0
- 都是 [
NaN
] - 都是同一個(gè)值雪情,非零且都不是 NaN
- 都是
Object.is(25, 25); // true
Object.is('foo', 'foo'); // true
Object.is('foo', 'bar'); // false
Object.is(null, null); // true
Object.is(undefined, undefined); // true
Object.is(window, window); // true
Object.is([], []); // false
var foo = { a: 1 };
var bar = { a: 1 };
Object.is(foo, foo); // true
Object.is(foo, bar); // false
5遵岩、freeze和isFrozen*
-
Object.freeze()
方法可以凍結(jié)一個(gè)對象。一個(gè)被凍結(jié)的對象再也不能被修改巡通;凍結(jié)了一個(gè)對象則不能向這個(gè)對象添加新的屬性尘执,不能刪除已有屬性,不能修改該對象已有屬性的可枚舉性宴凉、可配置性誊锭、可寫性,以及不能修改已有屬性的值弥锄。此外丧靡,凍結(jié)一個(gè)對象后該對象的原型也不能被修改。freeze()
返回和傳入的參數(shù)相同的對象籽暇。 -
Object.isFrozen()
方法判斷一個(gè)對象是否被[凍結(jié)]窘行。
// 一個(gè)對象默認(rèn)是可擴(kuò)展的,所以它也是非凍結(jié)的图仓。
Object.isFrozen({}); // === false
// 一個(gè)不可擴(kuò)展的空對象同時(shí)也是一個(gè)凍結(jié)對象罐盔。
var vacuouslyFrozen = Object.preventExtensions({});
Object.isFrozen(vacuouslyFrozen) //=== true;
// 一個(gè)非空對象默認(rèn)也是非凍結(jié)的。
var oneProp = { p: 42 };
Object.isFrozen(oneProp) //=== false
// 讓這個(gè)對象變的不可擴(kuò)展救崔,并不意味著這個(gè)對象變成了凍結(jié)對象惶看,
// 因?yàn)?p 屬性仍然是可以配置的 (而且可寫的).
Object.preventExtensions(oneProp);
Object.isFrozen(oneProp) //=== false
// 此時(shí)盹牧,如果刪除了這個(gè)屬性膳灶,則它會(huì)成為一個(gè)凍結(jié)對象涎嚼。
delete oneProp.p;
Object.isFrozen(oneProp) //=== true
// 一個(gè)不可擴(kuò)展的對象愉粤,擁有一個(gè)不可寫但可配置的屬性,則它仍然是非凍結(jié)的矾麻。
var nonWritable = { e: "plep" };
Object.preventExtensions(nonWritable);
Object.defineProperty(nonWritable, "e", { writable: false }); // 變得不可寫
Object.isFrozen(nonWritable) //=== false
// 把這個(gè)屬性改為不可配置闻蛀,會(huì)讓這個(gè)對象成為凍結(jié)對象仙蛉。
Object.defineProperty(nonWritable, "e", { configurable: false }); // 變得不可配置
Object.isFrozen(nonWritable) //=== true
// 一個(gè)不可擴(kuò)展的對象,擁有一個(gè)不可配置但可寫的屬性冠息,則它仍然是非凍結(jié)的挪凑。
var nonConfigurable = { release: "the kraken!" };
Object.preventExtensions(nonConfigurable);
Object.defineProperty(nonConfigurable, "release", { configurable: false });
Object.isFrozen(nonConfigurable) //=== false
// 把這個(gè)屬性改為不可寫,會(huì)讓這個(gè)對象成為凍結(jié)對象逛艰。
Object.defineProperty(nonConfigurable, "release", { writable: false });
Object.isFrozen(nonConfigurable) //=== true
// 一個(gè)不可擴(kuò)展的對象躏碳,值擁有一個(gè)訪問器屬性,則它仍然是非凍結(jié)的散怖。
var accessor = { get food() { return "yum"; } };
Object.preventExtensions(accessor);
Object.isFrozen(accessor) //=== false
// ...但把這個(gè)屬性改為不可配置菇绵,會(huì)讓這個(gè)對象成為凍結(jié)對象。
Object.defineProperty(accessor, "food", { configurable: false });
Object.isFrozen(accessor) //=== true
// 使用 Object.freeze 是凍結(jié)一個(gè)對象最方便的方法镇眷。
var frozen = { 1: 81 };
Object.isFrozen(frozen) //=== false
Object.freeze(frozen);
Object.isFrozen(frozen) //=== true
// 一個(gè)凍結(jié)對象也是一個(gè)密封對象咬最。
Object.isSealed(frozen) //=== true
// 當(dāng)然,更是一個(gè)不可擴(kuò)展的對象欠动。
Object.isExtensible(frozen) //=== false
6丹诀、seal和isSealed*
-
Object.seal()
方法封閉一個(gè)對象,阻止添加新屬性并將所有現(xiàn)有屬性標(biāo)記為不可配置翁垂。當(dāng)前屬性的值只要原來是可寫的就可以改變。 -
Object.isSealed()
方法判斷一個(gè)對象是否被密封硝桩。
// 新建的對象默認(rèn)不是密封的沿猜。
var empty = {};
Object.isSealed(empty); // === false
// 如果你把一個(gè)空對象變的不可擴(kuò)展,則它同時(shí)也會(huì)變成個(gè)密封對象碗脊。
Object.preventExtensions(empty);
Object.isSealed(empty); // === true
// 但如果這個(gè)對象不是空對象啼肩,則它不會(huì)變成密封對象,因?yàn)槊芊鈱ο蟮乃凶陨韺傩员仨毷遣豢膳渲玫摹?var hasProp = { fee: "fie foe fum" };
Object.preventExtensions(hasProp);
Object.isSealed(hasProp); // === false
// 如果把這個(gè)屬性變的不可配置衙伶,則這個(gè)屬性也就成了密封對象祈坠。
Object.defineProperty(hasProp, 'fee', {
configurable: false
});
Object.isSealed(hasProp); // === true
// 最簡單的方法來生成一個(gè)密封對象,當(dāng)然是使用 Object.seal.
var sealed = {};
Object.seal(sealed);
Object.isSealed(sealed); // === true
// 一個(gè)密封對象同時(shí)也是不可擴(kuò)展的矢劲。
Object.isExtensible(sealed); // === false
// 一個(gè)密封對象也可以是一個(gè)凍結(jié)對象赦拘,但不是必須的。
Object.isFrozen(sealed); // === true 芬沉,所有的屬性都是不可寫的
var s2 = Object.seal({ p: 3 });
Object.isFrozen(s2); // === false躺同, 屬性"p"可寫
var s3 = Object.seal({ get p() { return 0; } });
Object.isFrozen(s3); // === true ,訪問器屬性不考慮可寫不可寫丸逸,只考慮是否可配置
7蹋艺、preventExtensions和isExtensible*
-
Object.preventExtensions()
方法讓一個(gè)對象變的不可擴(kuò)展,也就是永遠(yuǎn)不能再添加新的屬性黄刚。 -
Object.isExtensible()
方法判斷一個(gè)對象是否是可擴(kuò)展的(是否可以在它上面添加新的屬性)捎谨。
// 新對象默認(rèn)是可擴(kuò)展的。
var empty = {};
Object.isExtensible(empty); // === true
// ...可以變的不可擴(kuò)展。
Object.preventExtensions(empty);
Object.isExtensible(empty); // === false
// 密封對象是不可擴(kuò)展的涛救。
var sealed = Object.seal({});
Object.isExtensible(sealed); // === false
// 凍結(jié)對象也是不可擴(kuò)展畏邢。
var frozen = Object.freeze({});
Object.isExtensible(frozen); // === false
8、getPrototype和setPrototypeOf*
-
Object.getPrototypeOf()
方法返回指定對象的原型(內(nèi)部[[Prototype]]
屬性的值)州叠。 -
Object.setPrototypeOf() 方法設(shè)置一個(gè)指定的對象的原型 ( 即棵红,內(nèi)部 [[Prototype]] 屬性)到另一個(gè)對象或 [
null
]。
let obj = {}
Object.setPrototypeOf(obj,{
username:'jack',
age:18
})
console.log(obj.username);//obj的這個(gè)原型上進(jìn)行設(shè)置
console.log(obj.age);//obj的這個(gè)原型上進(jìn)行設(shè)置
let obj1 = new Object()
console.log(obj1.username); //undefined
//getPrototypeOf 獲取指向的原型對象
let pro = Object.getPrototypeOf(obj)
let obj1Pro = Object.getPrototypeOf(obj1)
console.log(pro); //{username:'jack',age:18}
console.log(pro == Object.prototype);//false
console.log(obj1Pro == Object.prototype);//Object.prototype true
9咧栗、getOwnPropertyDescriptor 和getOwnPropertyDescriptors *
-
Object.getOwnPropertyDescriptor()
方法返回指定對象上一個(gè)自有屬性對應(yīng)的屬性描述符逆甜。(自有屬性指的是直接賦予該對象的屬性,不需要從原型鏈上進(jìn)行查找的屬性) -
Object.getOwnPropertyDescriptors()
方法用來獲取一個(gè)對象的所有自身屬性的描述符致板。
let obj = {
name:'jack'
}
//getOwnPropertyDescriptorc 獲取屬性的詳情信息 返回一個(gè)屬性對象(es的內(nèi)置對象)
let property = Object.getOwnPropertyDescriptor(obj,'name')
console.log(property);
//獲取所有的屬性詳情信息 返回也是一個(gè)對象 這個(gè)對象里面包含對應(yīng)的key 值為對應(yīng)的屬性對象
let objs = Object.getOwnPropertyDescriptors(obj)
console.log(objs);
10交煞、getOwnPropertyNames和getOwnProperSymbols
-
Object.getOwnPropertyNames()
方法返回一個(gè)由指定對象的所有自身屬性的屬性名(包括不可枚舉屬性但不包括 Symbol 值作為名稱的屬性)組成的數(shù)組。 -
Object.getOwnPropertySymbols()
方法返回一個(gè)給定對象自身的所有 Symbol 屬性的數(shù)組斟或。
//獲取所有的屬性名 組成一個(gè)數(shù)組或者是偽數(shù)組
console.log(Object.getOwnPropertyNames(obj));
let sy = Symbol()
obj[sy] = 'hello'//屬性名為symbol的屬性
//獲取所有屬性名為symbol值的屬性
console.log(Object.getOwnPropertySymbols(obj));
11素征、defineProperty***
Object.defineProperty()
方法會(huì)直接在一個(gè)對象上定義一個(gè)新屬性,或者修改一個(gè)對象的現(xiàn)有屬性萝挤,并返回此對象御毅。
let obj = {}
//給對象添加屬性
// defineProperty 定義一個(gè)屬性 參數(shù)是對象 屬性名 屬性對象
// (屬性對象 value 對應(yīng)的值 writeable 是否可以修改 enumerable 是否可以遍歷 configurable 刪除可以刪除)
Object.defineProperty(obj,'name',{
value:'jack',
writable:true, //可以修改
enumerable:true, //可以遍歷 for in
configurable:true //可以刪除
})
console.log(obj); //多一個(gè)name屬性
obj.name = 'hello' //跟writable屬性相關(guān)為false就不能修改
delete obj.name //跟configurable相關(guān) 為false 不能刪除
console.log(obj);
for(let key in obj){
console.log(key); //enumerable為false 就不能進(jìn)行遍歷
}
屬性對象的基礎(chǔ)屬性
- value:該屬性對應(yīng)的值×洌可以是任何有效的 JavaScript 值(數(shù)值端蛆,對象,函數(shù)等)酥泛。 默認(rèn)為 undefined
-
writable:當(dāng)且僅當(dāng)該屬性的
writable
鍵值為true
時(shí)今豆,屬性的值,也就是上面的value
柔袁,才能被賦值運(yùn)算符改變呆躲。 默認(rèn)為false
。 -
enumerable:當(dāng)且僅當(dāng)該屬性的
enumerable
鍵值為true
時(shí)捶索,該屬性才會(huì)出現(xiàn)在對象的枚舉屬性中插掂。 默認(rèn)為false
。 -
configurable:當(dāng)且僅當(dāng)該屬性的
configurable
鍵值為true
時(shí)腥例,該屬性的描述符才能夠被改變燥筷,同時(shí)該屬性也能從對應(yīng)的對象上被刪除。 默認(rèn)為false
院崇。
屬性對象的訪問器屬性
注意:已經(jīng)存在的情況才可以調(diào)用
get:屬性的 getter 函數(shù)肆氓,如果沒有 getter,則為
undefined
底瓣。當(dāng)訪問該屬性時(shí)谢揪,會(huì)調(diào)用此函數(shù)蕉陋。執(zhí)行時(shí)不傳入任何參數(shù),但是會(huì)傳入this
對象(由于繼承關(guān)系拨扶,這里的this
并不一定是定義該屬性的對象)凳鬓。該函數(shù)的返回值會(huì)被用作屬性的值。 **默認(rèn)為 [undefined
]患民。set:屬性的 setter 函數(shù)缩举,如果沒有 setter,則為
undefined
匹颤。當(dāng)屬性值被修改時(shí)仅孩,會(huì)調(diào)用此函數(shù)。該方法接受一個(gè)參數(shù)(也就是被賦予的新值)印蓖,會(huì)傳入賦值時(shí)的this
對象辽慕。 默認(rèn)為 [undefined
]。enumerable
configurable
//以訪問器屬性來寫(后面的倆個(gè)內(nèi)容可以不寫默認(rèn)為false)
Object.defineProperty(obj,'age',{
set(value){ //設(shè)置值的時(shí)候調(diào)用 value等于后面?zhèn)鬟f的值
console.log('set執(zhí)行了');
mockObj.age = value
},
get(){ //獲取值的時(shí)候
console.log('get執(zhí)行了');
return mockObj.age
},
// enumerable:true, //可以遍歷 for in
// configurable:true //可以刪除
})
console.log(obj.age); //調(diào)用了get的返回值
obj.age = 20 //調(diào)用了set方法
console.log(obj.age); //調(diào)用了get的返回值
delete obj.age
console.log(obj.age);
console.log(obj);
擴(kuò)展:vue2是由對應(yīng)的Object.defineProperty和觀察者模式實(shí)現(xiàn)赦肃。
12溅蛉、Object.defineProperties
Object.defineProperties
本質(zhì)上定義了 obj
對象上 props
的可枚舉屬性相對應(yīng)的所有屬性。
// defineProperties 定義多個(gè)屬性 對象 屬性對象
let object = {
}
Object.defineProperties(object,{
name:{
writable:true,
value:"張三",
enumerable:true,
configurable:true
},
sex:{
// writable:true,
// value:"男",
enumerable:true,
configurable:true,
get(){
return '男'
},
set(value){
console.log('設(shè)置方法調(diào)用了')
}
}
})
console.log(object);
四他宛、vue2雙向數(shù)據(jù)綁定實(shí)現(xiàn)
1船侧、v-model來實(shí)現(xiàn)雙向數(shù)據(jù)綁定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="text" v-model="message">
{{message}}
</div>
<script src="./lib/vue.js"></script>
<script>
new Vue({
el: "#app",
data: {
message:"你好啊"
}
})
</script>
</body>
</html>
2、底層實(shí)現(xiàn)(模擬實(shí)現(xiàn))
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="text" v-model="message">
{{message}}
<input type="text" v-model="title">
{{title}}
</div>
</body>
<script>
class Vue {
constructor(option) {
this.option = option
//通過對應(yīng)的el屬性傳入的選擇器選擇對應(yīng)的元素
this.el = document.querySelector(option['el'])
//提取data
this.data = option['data']
//虛擬對象
this.mockData = {}
//獲取初始的模板
this.template = this.el.innerHTML
this.rander() //初次渲染
this.wacth() //調(diào)用監(jiān)聽
}
rander() {
let that = this
//讀取{{}}包起來的內(nèi)容 替換
//{{}}
this.el.innerHTML = this.template.replace(/\{\{[\w.]+\}\}/g, function (v) { //表示匹配的內(nèi)容
// v {{message}} ==> 你好啊
let key = v.substr(2, v.length - 4)
return that.data[key] //調(diào)用get
})
//讀取對應(yīng)的input的v-model屬性
//找所有的input框 在input在所有有對應(yīng)的v-model屬性 將他里面的value值變了
Array.from(this.el.querySelectorAll('input'))
//得到所有代理v-model屬性的input框
.filter((input) => input.attributes['v-model'])
//接著遍歷
.forEach(vmInput => {
//給對應(yīng)的value進(jìn)行賦值
vmInput.value = that.data[vmInput.getAttribute('v-model')] //調(diào)用get
//給對應(yīng)的input框添加事件 oninput事件
vmInput.oninput = function () {//觀察者
that.data[vmInput.getAttribute('v-model')] = this.value //調(diào)set
vmInput.focus() //獲取焦點(diǎn)
}
})
}
//監(jiān)聽
wacth() {
let _this = this
Object.keys(this.data).forEach(key => {
_this.mockData[key] = _this.data[key] //初始賦值操作
Object.defineProperty(_this.data, key, {
get() {
return _this.mockData[key]
},
set(value) {
_this.mockData[key] = value
_this.rander()
}
})
})
}
}
new Vue({
el: "#app",
data: {
message: "你好啊",
title:'你好'
}
})
</script>
</html>