huangxubo23 / front-end-developer Goto Github PK
View Code? Open in Web Editor NEWJavaScript实践代码
JavaScript实践代码
在大多数情况下,由于JavaScript是弱类型语言,所以它声明的变量是可以动态赋值和改变数据类型的。变量是变量的本身,它不基于另外一个变量衍生出来。
但是有的时候,我们想要在一个已有的变量的基础上来创建和衍生出另外一个变量。例如,我们有个person的对象来保存用户的姓名信息,如果我们想改变已有的姓名信息后立刻看到新的信息,一般的代码我们会这样写:
//某程序员在网上交了个女朋友
var person = {
firstName: '苍',
lastName: '女神',
setFirstName: function(name){
this.firstName = name;
},
setLastName: function(name){
this.lastName = name;
},
getFullName: function() {
return this.firstName + this.lastName;
}
};
console.log(person.getFullName()); //苍女神
//后来发现苍女神并不是他的真爱,通过漫长的等待终于找到了她
person.setFirstName('女');
person.setLastName('汉子');
console.log(person.getFullName()); //女汉子
这种方式并不够简洁优美,因为我们只能根据person对象的setFirstName()和setLastName()方法来分别设置姓名,然后再通过getFullName()方法来获取信息。这样的操作难免会有些繁琐,那么我们是否有更好的方法来简化我们记录信息的流程?幸运的是,ECMAScript 5 为我们提供一种更好的方式——setter和getter。
现在我们使用setter和getter来重新构建person对象,这个对象允许我们分别设置姓、名和全名,而且其中的一个属性发生改变时,另外两个也将自动更新:
var person = {
firstName: '女',
lastName: '汉子',
get fullName(){
return this.firstName + this.lastName;
},
set fullName(name){
var words = name.toString().split('-');
this.firstName = words[0] || '';
this.lastName = words[1] || '';
}
}
console.log(person.fullName) //女汉子
person.fullName = '白-富美';
console.log(person.firstName); //白
console.log(person.lastName); //富美
console.log(person.fullName); //白富美
在上面的代码中,person中的set和get的关键字是非常重要的。当属性被设置或修改时(person.fullName = '白-富美';),会调用set后面的fullName函数;当属性被访问或引用时(person.fullName),会调用get后面的fullName函数。这样,我们可以在对象中使用同一个属性,通过set和get来实现使用对象的设置(修改)和访问(引用)。
在上面person对象的例子中,可以使用官方推荐的 Object.defineProperty(查看MDN文档)的方法来实现。
官方定义:The Object.defineProperty() method defines a new property directly on an object, or modifies an existing property on an object, and returns the object.
Object.defineProperty(obj, prop, descriptor)
参数 | 说明 |
---|---|
obj | 基于该对象来定义拓展属性 |
prop | 要定义或修改的属性名称 |
descriptor | 属性定义或修改的描述符(值) |
使用Object.defineProperty,除了能够基于某一对象来添加或修改属性之外,还有没有其它的好处吗?
其实,通过Object.defineProperty来定义对象属性时,除了使用setter和getter之外,还可以使用下面的配置:
在使用Object.defineProperty定义对象的属性时,可以使用value对其直接赋值,例如:
Object.defineProperty(person, 'age', {
value: 18
});
person.age = 23;
console.log(person.age) //18
上面的代码将会在person对象上的age属性直接把值设为18,而且默认为只读(因为在descriptor中writable默认为false),所以即使通过后面person.age = 23;也不能对age属性重新赋值。另外,如果在descriptor使用value在设置值时,就不能再使用setter和getter,因为descriptor中不能同时设置属性值(value)和访问器(setter/getter)。
如果我们想使age属性可写,我们需要设置writable为true,代码修改为:
Object.defineProperty(person, 'age', {
value: 18,
writable: true
});
person.age = 23;
console.log(person.age) //23
setter和getter有自己的使用场景和用例,如果仅仅只是对象进行简单的属性赋值时,并不需要使用setter和setter,因为滥用setter和getter会让原本简单的对象赋值变得杂乱。
Object.defineProperty的兼容性:
浏览器 | 支持版本 |
---|---|
IE | IE9+ |
Chrome | 5+ |
Firefox | 4+ |
Safari | 5+ |
Opera | 12+ |
Node | 全部支持 |
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.