Object.defineProperty()函數(shù)之屬性描述對(duì)象
概述
JavaScript 提供了一個(gè)內(nèi)部數(shù)據(jù)結(jié)構(gòu),用來(lái)描述對(duì)象的屬性,控制它的行為,比如該屬性是否可寫(xiě)、可遍歷等等。這個(gè)內(nèi)部數(shù)據(jù)結(jié)構(gòu)稱為“屬性描述對(duì)象”(attributes object)。每個(gè)屬性都有自己對(duì)應(yīng)的屬性描述對(duì)象,保存該屬性的一些元信息。
下面是屬性描述對(duì)象的一個(gè)例子:
{ value: 123, writable: false, enumerable: true, configurable: false, get: undefined, set: undefined }
屬性描述對(duì)象提供6個(gè)元屬性。
(1)value
value
是該屬性的屬性值,默認(rèn)為undefined
。
(2)writable
writable
是一個(gè)布爾值,表示屬性值(value)是否可改變(即是否可寫(xiě)),默認(rèn)為true
。
(3)enumerable
enumerable
是一個(gè)布爾值,表示該屬性是否可遍歷,默認(rèn)為true
。如果設(shè)為false
,會(huì)使得某些操作(比如for...in
循環(huán)、Object.keys()
)跳過(guò)該屬性。
(4)configurable
configurable
是一個(gè)布爾值,表示可配置性,默認(rèn)為true
。如果設(shè)為false
,將阻止某些操作改寫(xiě)該屬性,比如無(wú)法刪除該屬性,也不得改變?cè)搶傩缘膶傩悦枋鰧?duì)象(value
屬性除外)。也就是說(shuō),configurable
屬性控制了屬性描述對(duì)象的可寫(xiě)性。
(5)get
get
是一個(gè)函數(shù),表示該屬性的取值函數(shù)(getter),默認(rèn)為undefined
。
(6)set
set
是一個(gè)函數(shù),表示該屬性的存值函數(shù)(setter),默認(rèn)為undefined
。
Object.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptor
方法可以獲取屬性描述對(duì)象。它的第一個(gè)參數(shù)是一個(gè)對(duì)象,第二個(gè)參數(shù)是一個(gè)字符串,對(duì)應(yīng)該對(duì)象的某個(gè)屬性名。
var obj = { p: 'a' }; Object.getOwnPropertyDescriptor(obj, 'p') // Object { value: "a", // writable: true, // enumerable: true, // configurable: true // }
上面代碼中,Object.getOwnPropertyDescriptor
方法獲取obj.p
的屬性描述對(duì)象。
注意:Object.getOwnPropertyDescriptor
方法只能用于對(duì)象自身的屬性,不能用于繼承的屬性。
var obj = { p: 'a' }; Object.getOwnPropertyDescriptor(obj, 'toString') // undefined
上面代碼中,toString
是Obj
對(duì)象繼承的屬性,Object.getOwnPropertyDescriptor
無(wú)法獲取。
Object.getOwnPropertyNames()
Object.getOwnPropertyNames
方法返回一個(gè)數(shù)組,成員是參數(shù)對(duì)象自身的全部屬性的屬性名,不管該屬性是否可遍歷。
var obj = Object.defineProperties({}, { p1: { value: 1, enumerable: true }, p2: { value: 2, enumerable: false } }); Object.getOwnPropertyNames(obj) // ["p1", "p2"]
上面代碼中,obj.p1
是可遍歷的,obj.p2
是不可遍歷的。Object.getOwnPropertyNames
會(huì)將它們都返回。
這跟Object.keys
的行為不同,Object.keys
只返回對(duì)象自身的可遍歷屬性的全部屬性名。
Object.keys([]) // [] Object.getOwnPropertyNames([]) // [ 'length' ] Object.keys(Object.prototype) // [] Object.getOwnPropertyNames(Object.prototype) // ['hasOwnProperty', // 'valueOf', // 'constructor', // 'toLocaleString', // 'isPrototypeOf', // 'propertyIsEnumerable', // 'toString']
上面代碼中,數(shù)組自身的length
屬性是不可遍歷的,Object.keys
不會(huì)返回該屬性。第二個(gè)例子的Object.prototype
也是一個(gè)對(duì)象,所有實(shí)例對(duì)象都會(huì)繼承它,它自身的屬性都是不可遍歷的。
Object.defineProperty(),Object.defineProperties()
Object.defineProperty
方法允許通過(guò)屬性描述對(duì)象,定義或修改一個(gè)屬性,然后返回修改后的對(duì)象,它的用法如下。
Object.defineProperty(object, propertyName, attributesObject)
Object.defineProperty
方法接受三個(gè)參數(shù),
依次如下:
- 屬性所在的對(duì)象
- 屬性名(它應(yīng)該是一個(gè)字符串)
- 屬性描述對(duì)象
舉例來(lái)說(shuō),定義obj.p
可以寫(xiě)成下面這樣。
var obj = Object.defineProperty({}, 'p', { value: 123, writable: false, enumerable: true, configurable: false }); obj.p // 123 obj.p = 246; obj.p // 123
上面代碼中,Object.defineProperty
方法定義了obj.p
屬性。由于屬性描述對(duì)象的writable
屬性為false
,所以obj.p
屬性不可寫(xiě)。注意,這里的Object.defineProperty
方法的第一個(gè)參數(shù)是{}
(一個(gè)新建的空對(duì)象),p
屬性直接定義在這個(gè)空對(duì)象上面,然后返回這個(gè)對(duì)象,這是Object.defineProperty
的常見(jiàn)寫(xiě)法。
如果屬性已經(jīng)存在,Object.defineProperty
方法相當(dāng)于更新該屬性的屬性描述對(duì)象。
如果一次性定義或修改多個(gè)屬性,可以使用Object.defineProperties
方法。
var obj = Object.defineProperties({}, { p1: { value: 123, enumerable: true }, p2: { value: 'abc', enumerable: true }, p3: { get: function () { return this.p1 + this.p2 }, enumerable:true, configurable:true } }); obj.p1 // 123 obj.p2 // "abc" obj.p3 // "123abc"
上面代碼中,Object.defineProperties
同時(shí)定義了obj
對(duì)象的三個(gè)屬性。其中,p3
屬性定義了取值函數(shù)get
,即每次讀取該屬性,都會(huì)調(diào)用這個(gè)取值函數(shù)。
注意,一旦定義了取值函數(shù)get
(或存值函數(shù)set
),就不能將writable
屬性設(shè)為true
,或者同時(shí)定義value
屬性,否則會(huì)報(bào)錯(cuò)。
var obj = {}; Object.defineProperty(obj, 'p', { value: 123, get: function() { return 456; } }); // TypeError: Invalid property. // A property cannot both have accessors and be writable or have a value Object.defineProperty(obj, 'p', { writable: true, get: function() { return 456; } }); // TypeError: Invalid property descriptor. // Cannot both specify accessors and a value or writable attribute
上面代碼中,同時(shí)定義了get
屬性和value
屬性,以及將writable
屬性設(shè)為true
,就會(huì)報(bào)錯(cuò)。
Object.defineProperty()
和Object.defineProperties()
的第三個(gè)參數(shù),是一個(gè)屬性對(duì)象。它的writable
、configurable
、enumerable
這三個(gè)屬性的默認(rèn)值都為false
。
var obj = {}; Object.defineProperty(obj, 'foo', {}); Object.getOwnPropertyDescriptor(obj, 'foo') // { // value: undefined, // writable: false, // enumerable: false, // configurable: false // }
上面代碼中,定義obj.p
時(shí)用了一個(gè)空的屬性描述對(duì)象,就可以看到各個(gè)元屬性的默認(rèn)值。
Object.prototype.propertyIsEnumerable()
實(shí)例對(duì)象的propertyIsEnumerable
方法返回一個(gè)布爾值,用來(lái)判斷某個(gè)屬性是否可遍歷。
var obj = {}; obj.p = 123; obj.propertyIsEnumerable('p') // true obj.propertyIsEnumerable('toString') // false
上面代碼中,obj.p
是可遍歷的,而繼承自原型對(duì)象的obj.toString
屬性是不可遍歷的。
元屬性
屬性描述對(duì)象的各個(gè)屬性稱為“元屬性”,因?yàn)樗鼈兛梢钥醋魇强刂茖傩缘膶傩浴?/p>
value
value
屬性是目標(biāo)屬性的值。
var obj = {}; obj.p = 123; Object.getOwnPropertyDescriptor(obj, 'p').value // 123 Object.defineProperty(obj, 'p', { value: 246 }); obj.p // 246
上面代碼是通過(guò)value
屬性,讀取或改寫(xiě)obj.p
的例子。
writable
writable
屬性是一個(gè)布爾值,決定了目標(biāo)屬性的值(value)是否可以被改變。
var obj = {}; Object.defineProperty(obj, 'a', { value: 37, writable: false }); obj.a // 37 obj.a = 25; obj.a // 37
上面代碼中,obj.a
的writable
屬性是false
。然后,改變obj.a
的值,不會(huì)有任何效果。
注意:正常模式下,對(duì)writable
為false
的屬性賦值不會(huì)報(bào)錯(cuò),只會(huì)默默失敗。但是,嚴(yán)格模式下會(huì)報(bào)錯(cuò),即使對(duì)a
屬性重新賦予一個(gè)同樣的值。
'use strict'; var obj = {}; Object.defineProperty(obj, 'a', { value: 37, writable: false }); obj.a = 37; // Uncaught TypeError: Cannot assign to read only property 'a' of object
上面代碼是嚴(yán)格模式,對(duì)obj.a
任何賦值行為都會(huì)報(bào)錯(cuò)。
如果原型對(duì)象的某個(gè)屬性的writable
為false
,那么子對(duì)象將無(wú)法自定義這個(gè)屬性。
var proto = Object.defineProperty({}, 'foo', { value: 'a', writable: false }); var obj = Object.create(proto); obj.foo = 'b'; obj.foo // 'a'
上面代碼中,proto
是原型對(duì)象,它的foo
屬性不可寫(xiě)。obj
對(duì)象繼承proto
,也不可以再自定義這個(gè)屬性了。如果是嚴(yán)格模式,這樣做還會(huì)拋出一個(gè)錯(cuò)誤。
但是,有一個(gè)規(guī)避方法,就是通過(guò)覆蓋屬性描述對(duì)象,繞過(guò)這個(gè)限制。原因是這種情況下,原型鏈會(huì)被完全忽視。
var proto = Object.defineProperty({}, 'foo', { value: 'a', writable: false }); var obj = Object.create(proto); Object.defineProperty(obj, 'foo', { value: 'b' }); obj.foo // "b"
enumerable
enumerable
(可遍歷性)返回一個(gè)布爾值,表示目標(biāo)屬性是否可遍歷。
JavaScript 的早期版本,for...in
循環(huán)是基于in
運(yùn)算符的。我們知道,in
運(yùn)算符不管某個(gè)屬性是對(duì)象自身的還是繼承的,都會(huì)返回true
。
var obj = {}; 'toString' in obj // true
上面代碼中,toString
不是obj
對(duì)象自身的屬性,但是in
運(yùn)算符也返回true
,這導(dǎo)致了toString
屬性也會(huì)被for...in
循環(huán)遍歷。
這顯然不太合理,后來(lái)就引入了“可遍歷性”這個(gè)概念。只有可遍歷的屬性,才會(huì)被for...in
循環(huán)遍歷,同時(shí)還規(guī)定toString
這一類(lèi)實(shí)例對(duì)象繼承的原生屬性,都是不可遍歷的,這樣就保證了for...in
循環(huán)的可用性。
具體來(lái)說(shuō),如果一個(gè)屬性的enumerable
為false
,
下面三個(gè)操作不會(huì)取到該屬性:
for..in
循環(huán)Object.keys
方法JSON.stringify
方法
因此,enumerable
可以用來(lái)設(shè)置“秘密”屬性。
var obj = {}; Object.defineProperty(obj, 'x', { value: 123, enumerable: false }); obj.x // 123 for (var key in obj) { console.log(key); } // undefined Object.keys(obj) // [] JSON.stringify(obj) // "{}"
上面代碼中,obj.x
屬性的enumerable
為false
,所以一般的遍歷操作都無(wú)法獲取該屬性,使得它有點(diǎn)像“秘密”屬性,但不是真正的私有屬性,還是可以直接獲取它的值。
注意:for...in
循環(huán)包括繼承的屬性,Object.keys
方法不包括繼承的屬性。如果需要獲取對(duì)象自身的所有屬性,不管是否可遍歷,可以使用Object.getOwnPropertyNames
方法。
另外,JSON.stringify
方法會(huì)排除enumerable
為false
的屬性,有時(shí)可以利用這一點(diǎn)。如果對(duì)象的 JSON 格式輸出要排除某些屬性,就可以把這些屬性的enumerable
設(shè)為false
。
configurable
configurable
(可配置性)返回一個(gè)布爾值,決定了是否可以修改屬性描述對(duì)象。也就是說(shuō),configurable
為false
時(shí),value
、writable
、enumerable
和configurable
都不能被修改了。
var obj = Object.defineProperty({}, 'p', { value: 1, writable: false, enumerable: false, configurable: false }); Object.defineProperty(obj, 'p', {value: 2}) // TypeError: Cannot redefine property: p Object.defineProperty(obj, 'p', {writable: true}) // TypeError: Cannot redefine property: p Object.defineProperty(obj, 'p', {enumerable: true}) // TypeError: Cannot redefine property: p Object.defineProperty(obj, 'p', {configurable: true}) // TypeError: Cannot redefine property: p
上面代碼中,obj.p
的configurable
為false
。然后,改動(dòng)value
、writable
、enumerable
、configurable
,結(jié)果都報(bào)錯(cuò)。
注意:writable
只有在false
改為true
會(huì)報(bào)錯(cuò),true
改為false
是允許的。
var obj = Object.defineProperty({}, 'p', { writable: true, configurable: false }); Object.defineProperty(obj, 'p', {writable: false}) // 修改成功
至于value
,只要writable
和configurable
有一個(gè)為true
,就允許改動(dòng)。
var o1 = Object.defineProperty({}, 'p', { value: 1, writable: true, configurable: false }); Object.defineProperty(o1, 'p', {value: 2}) // 修改成功 var o2 = Object.defineProperty({}, 'p', { value: 1, writable: false, configurable: true }); Object.defineProperty(o2, 'p', {value: 2}) // 修改成功
另外,configurable
為false
時(shí),直接目標(biāo)屬性賦值,不報(bào)錯(cuò),但不會(huì)成功。
var obj = Object.defineProperty({}, 'p', { value: 1, configurable: false }); obj.p = 2; obj.p // 1
上面代碼中,obj.p
的configurable
為false
,對(duì)obj.p
賦值是不會(huì)生效的。如果是嚴(yán)格模式,還會(huì)報(bào)錯(cuò)。
可配置性決定了目標(biāo)屬性是否可以被刪除(delete)。
var obj = Object.defineProperties({}, { p1: { value: 1, configurable: true }, p2: { value: 2, configurable: false } }); delete obj.p1 // true delete obj.p2 // false obj.p1 // undefined obj.p2 // 2
上面代碼中,obj.p1
的configurable
是true
,所以可以被刪除,obj.p2
就無(wú)法刪除。
存取器
除了直接定義以外,屬性還可以用存取器(accessor)定義。其中,存值函數(shù)稱為setter
,使用屬性描述對(duì)象的set
屬性;取值函數(shù)稱為getter
,使用屬性描述對(duì)象的get
屬性。
一旦對(duì)目標(biāo)屬性定義了存取器,那么存取的時(shí)候,都將執(zhí)行對(duì)應(yīng)的函數(shù)。利用這個(gè)功能,可以實(shí)現(xiàn)許多高級(jí)特性,比如某個(gè)屬性禁止賦值。
var obj = Object.defineProperty({}, 'p', { get: function () { return 'getter'; }, set: function (value) { console.log('setter: ' + value); } }); obj.p // "getter" obj.p = 123 // "setter: 123"
上面代碼中,obj.p
定義了get
和set
屬性。obj.p
取值時(shí),就會(huì)調(diào)用get
;賦值時(shí),就會(huì)調(diào)用set
。
JavaScript 還提供了存取器的另一種寫(xiě)法。
var obj = { get p() { return 'getter'; }, set p(value) { console.log('setter: ' + value); } };
上面的寫(xiě)法與定義屬性描述對(duì)象是等價(jià)的,而且使用更廣泛。
注意,取值函數(shù)get
不能接受參數(shù),存值函數(shù)set
只能接受一個(gè)參數(shù)(即屬性的值)。
存取器往往用于,屬性的值依賴對(duì)象內(nèi)部數(shù)據(jù)的場(chǎng)合。
var obj ={ $n : 5, get next() { return this.$n++ }, set next(n) { if (n >= this.$n) this.$n = n; else throw new Error('新的值必須大于當(dāng)前值'); } }; obj.next // 5 obj.next = 10; obj.next // 10 obj.next = 5; // Uncaught Error: 新的值必須大于當(dāng)前值
上面代碼中,next
屬性的存值函數(shù)和取值函數(shù),都依賴于內(nèi)部屬性$n
。
對(duì)象的拷貝
有時(shí),我們需要將一個(gè)對(duì)象的所有屬性,拷貝到另一個(gè)對(duì)象,可以用下面的方法實(shí)現(xiàn)。
var extend = function (to, from) { for (var property in from) { to[property] = from[property]; } return to; } extend({}, { a: 1 }) // {a: 1}
上面這個(gè)方法的問(wèn)題在于,如果遇到存取器定義的屬性,會(huì)只拷貝值。
extend({}, { get a() { return 1 } }) // {a: 1}
為了解決這個(gè)問(wèn)題,我們可以通過(guò)Object.defineProperty
方法來(lái)拷貝屬性。
var extend = function (to, from) { for (var property in from) { if (!from.hasOwnProperty(property)) continue; Object.defineProperty( to, property, Object.getOwnPropertyDescriptor(from, property) ); } return to; } extend({}, { get a(){ return 1 } }) // { get a(){ return 1 } })
上面代碼中,hasOwnProperty
那一行用來(lái)過(guò)濾掉繼承的屬性,否則會(huì)報(bào)錯(cuò),因?yàn)?code>Object.getOwnPropertyDescriptor讀不到繼承屬性的屬性描述對(duì)象。
控制對(duì)象狀態(tài)
有時(shí)需要凍結(jié)對(duì)象的讀寫(xiě)狀態(tài),防止對(duì)象被改變。JavaScript 提供了三種凍結(jié)方法,最弱的一種是Object.preventExtensions
,其次是Object.seal
,最強(qiáng)的是Object.freeze
。
Object.preventExtensions()
Object.preventExtensions
方法可以使得一個(gè)對(duì)象無(wú)法再添加新的屬性。
var obj = new Object(); Object.preventExtensions(obj); Object.defineProperty(obj, 'p', { value: 'hello' }); // TypeError: Cannot define property:p, object is not extensible. obj.p = 1; obj.p // undefined
上面代碼中,obj
對(duì)象經(jīng)過(guò)Object.preventExtensions
以后,就無(wú)法添加新屬性了。
Object.isExtensible()
Object.isExtensible
方法用于檢查一個(gè)對(duì)象是否使用了Object.preventExtensions
方法。也就是說(shuō),檢查是否可以為一個(gè)對(duì)象添加屬性。
var obj = new Object(); Object.isExtensible(obj) // true Object.preventExtensions(obj); Object.isExtensible(obj) // false
上面代碼中,對(duì)obj
對(duì)象使用Object.preventExtensions
方法以后,再使用Object.isExtensible
方法,返回false
,表示已經(jīng)不能添加新屬性了。
Object.seal()
Object.seal
方法使得一個(gè)對(duì)象既無(wú)法添加新屬性,也無(wú)法刪除舊屬性。
var obj = { p: 'hello' }; Object.seal(obj); delete obj.p; obj.p // "hello" obj.x = 'world'; obj.x // undefined
上面代碼中,obj
對(duì)象執(zhí)行Object.seal
方法以后,就無(wú)法添加新屬性和刪除舊屬性了。
Object.seal
實(shí)質(zhì)是把屬性描述對(duì)象的configurable
屬性設(shè)為false
,因此屬性描述對(duì)象不再能改變了。
var obj = { p: 'a' }; // seal方法之前 Object.getOwnPropertyDescriptor(obj, 'p') // Object { // value: "a", // writable: true, // enumerable: true, // configurable: true // } Object.seal(obj); // seal方法之后 Object.getOwnPropertyDescriptor(obj, 'p') // Object { // value: "a", // writable: true, // enumerable: true, // configurable: false // } Object.defineProperty(o, 'p', { enumerable: false }) // TypeError: Cannot redefine property: p
上面代碼中,使用Object.seal
方法之后,屬性描述對(duì)象的configurable
屬性就變成了false
,然后改變enumerable
屬性就會(huì)報(bào)錯(cuò)。
Object.seal
只是禁止新增或刪除屬性,并不影響修改某個(gè)屬性的值。
var obj = { p: 'a' }; Object.seal(obj); obj.p = 'b'; obj.p // 'b'
上面代碼中,Object.seal
方法對(duì)p
屬性的value
無(wú)效,是因?yàn)榇藭r(shí)p
屬性的可寫(xiě)性由writable
決定。
Object.isSealed()
Object.isSealed
方法用于檢查一個(gè)對(duì)象是否使用了Object.seal
方法。
var obj = { p: 'a' }; Object.seal(obj); Object.isSealed(obj) // true
這時(shí),Object.isExtensible
方法也返回false
。
var obj = { p: 'a' }; Object.seal(obj); Object.isExtensible(obj) // false
Object.freeze()
Object.freeze
方法可以使得一個(gè)對(duì)象無(wú)法添加新屬性、無(wú)法刪除舊屬性、也無(wú)法改變屬性的值,使得這個(gè)對(duì)象實(shí)際上變成了常量。
var obj = { p: 'hello' }; Object.freeze(obj); obj.p = 'world'; obj.p // "hello" obj.t = 'hello'; obj.t // undefined delete obj.p // false obj.p // "hello"
上面代碼中,對(duì)obj
對(duì)象進(jìn)行Object.freeze()
以后,修改屬性、新增屬性、刪除屬性都無(wú)效了。這些操作并不報(bào)錯(cuò),只是默默地失敗。如果在嚴(yán)格模式下,則會(huì)報(bào)錯(cuò)。
Object.isFrozen()
Object.isFrozen
方法用于檢查一個(gè)對(duì)象是否使用了Object.freeze
方法。
var obj = { p: 'hello' }; Object.freeze(obj); Object.isFrozen(obj) // true
使用Object.freeze
方法以后,Object.isSealed
將會(huì)返回true
,Object.isExtensible
返回false
。
var obj = { p: 'hello' }; Object.freeze(obj); Object.isSealed(obj) // true Object.isExtensible(obj) // false
Object.isFrozen
的一個(gè)用途是,確認(rèn)某個(gè)對(duì)象沒(méi)有被凍結(jié)后,再對(duì)它的屬性賦值。
var obj = { p: 'hello' }; Object.freeze(obj); if (!Object.isFrozen(obj)) { obj.p = 'world'; }
上面代碼中,確認(rèn)obj
沒(méi)有被凍結(jié)后,再對(duì)它的屬性賦值,就不會(huì)報(bào)錯(cuò)了。
局限性
上面的三個(gè)方法鎖定對(duì)象的可寫(xiě)性有一個(gè)漏洞:可以通過(guò)改變?cè)蛯?duì)象,來(lái)為對(duì)象增加屬性。
var obj = new Object(); Object.preventExtensions(obj); var proto = Object.getPrototypeOf(obj); proto.t = 'hello'; obj.t // hello
上面代碼中,對(duì)象obj
本身不能新增屬性,但是可以在它的原型對(duì)象上新增屬性,就依然能夠在obj
上讀到。
一種解決方案是,把obj
的原型也凍結(jié)住。
var obj = new Object(); Object.preventExtensions(obj); var proto = Object.getPrototypeOf(obj); Object.preventExtensions(proto); proto.t = 'hello'; obj.t // undefined
另外一個(gè)局限是,如果屬性值是對(duì)象,上面這些方法只能凍結(jié)屬性指向的對(duì)象,而不能凍結(jié)對(duì)象本身的內(nèi)容。
var obj = { foo: 1, bar: ['a', 'b'] }; Object.freeze(obj); obj.bar.push('c'); obj.bar // ["a", "b", "c"]
上面代碼中,obj.bar
屬性指向一個(gè)數(shù)組,obj
對(duì)象被凍結(jié)以后,這個(gè)指向無(wú)法改變,即無(wú)法指向其他值,但是所指向的數(shù)組是可以改變的。
到此這篇關(guān)于Object.defineProperty()函數(shù)之屬性描述對(duì)象的文章就介紹到這了,更多相關(guān)Object.defineProperty函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript實(shí)現(xiàn)鼠標(biāo)經(jīng)過(guò)表格行給出顏色標(biāo)識(shí)
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)鼠標(biāo)經(jīng)過(guò)表格行給出顏色標(biāo)識(shí),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-04-04阿里巴巴技術(shù)文章分享 Javascript繼承機(jī)制的實(shí)現(xiàn)
這篇文章主要介紹了阿里巴巴技術(shù)文章,分享的是一篇關(guān)于Javascript實(shí)現(xiàn)繼承機(jī)制的文章,感興趣的小伙伴們可以參考一下2016-01-01小程序雙頭slider選擇器的實(shí)現(xiàn)示例
這篇文章主要介紹了小程序雙頭slider選擇器的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03計(jì)算新浪Weibo消息長(zhǎng)度(還可以輸入119字)
此文為計(jì)算新浪Weibo的消息長(zhǎng)度的方法. 就是在發(fā)言的時(shí)候還可以輸入多少字,具體的實(shí)現(xiàn)如下,感興趣的朋友可以參考下哈,希望對(duì)大家有所幫助2013-07-07如何實(shí)現(xiàn)JavaScript動(dòng)態(tài)加載CSS和JS文件
這篇文章主要為大家詳細(xì)介紹了JavaScript動(dòng)態(tài)加載CSS和JS文件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2015-10-10js實(shí)現(xiàn)幻燈片效果(基于jquery插件)
說(shuō)起幻燈片效果,想必大家都不陌生吧,接下來(lái)為大家介紹下使用jquery插件jquery.smallslider.js實(shí)現(xiàn)幻燈片效果示例代碼,喜歡的朋友可以學(xué)習(xí)下2013-11-11前端開(kāi)發(fā)不得不知的10個(gè)最佳ES6特性
ES6已經(jīng)不再是JavaScript最新的標(biāo)準(zhǔn),但是它已經(jīng)廣泛用于編程實(shí)踐中。下面通過(guò)本文給大家分享前端開(kāi)發(fā)不得不知的10個(gè)最佳ES6特性,感興趣的朋友參考下吧2017-08-08