JavaScript大杂烩13 - 总结ECMAScript 5新功能
var Dog = {
name : 'dog',
speak : function () { alert('Woof!'); }
};
var dog = Object.create(Dog);
dog.speak();
这里就是使用了这个方法创建了Dog的一个实例dog,这种方式的本质其实还是与我们之前讨论的使用空对象挂接原型对象是一样的,代码基本就像这样:
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
使用这种方式较之使用构造函数加new的方式来说更加简洁,但是不能设置私有和公开成员,而且实例成员在各个实例之间不共享,所以也有一定的局限性。
Object.create(prototype, descriptors)
参数
prototype:必需。 要用作原型的对象。 可以为 null,一般也可以在需要的时候使用getPrototypeOf方法获取。
descriptors: 可选。 定义的一组属性的对象字面量,该对象包含了每个属性的描述对象。
属性描述对象称为属性的attributes对象,其含有如下成员:
value:表示该属性的值,默认为undefined。
writable:表示该属性的值(value)是否可以改变,默认为true。这个值如果是false的话,即使是继承的子类的话,也无法修改属性的值,这个也是讲得通的。
enumerable: 表示该属性是否可枚举,默认为true,也就是该属性会出现在for...in和Object.keys()等操作中。
configurable:表示“可配置性”,默认为true。如果设为false,表示无法删除该属性,也不得改变attributes对象(value属性除外),也就是configurable属性控制了attributes对象本身的可写性。
get:表示该属性的取值函数(getter),默认为undefined。
set:表示该属性的存值函数(setter),默认为undefined。
返回值
一个具有指定的内部原型且包含指定的属性(如果有)的新对象。
毫无疑问,这个函数最有意义的应该就是第二个参数:一组属性描述对象,这个在别的语言中非常有用的特性姗姗来迟,虽然在JavaScript中可以直接使用dog.age=2这种方式定义和修改属性,但是这种数据成员终究不满足封装性的需求,而且不满足属性本质上是函数这种惯例,在这个版本中满足封装性的属性(本质上是函数)终于出现在大家视野中了,我们看一个例子来了解一下如何定义一组属性:
var Shape = { twoDimensional: true, color: 'Red'};
var Square = Object.create(Shape, {
// 简单的属性,不包含任何的其他逻辑的属性
type: { value: 'square', enumerable: true, writable: true },
// 复杂一点的属性,包含有一些逻辑的属性
size: {
get: function() { return this.__size__;},
set: function(pSize) {
if (pSize > 10) alert('Too large...');
// 其他的处理逻辑,例如简单的保存一下
this.__size__ = pSize;
},
enumerable: true
}
});
var square = Object.create(Square);
square.type = 'rectangle';
alert(square.type);
square.size = 9;
alert(square.size);
使用起来还是很简单的,但是有一点不太优雅的代码就是this.__size__这个保存属性值的成员,为了满足封装性,我们得使用一下闭包的特性了:
var Square = Object.create(Shape, (function () {
var m_size; return {
// 简单的属性,不包含任何的其他逻辑的属性
type: { value: 'square', enumerable: true, writable: true },
// 复杂一点的属性,包含有一些逻辑的属性
size: {
get: function() { return m_size;},
set: function(pSize) {
// 常见的条件检查
if (pSize > 10) alert('Too large...');
// 其他的处理逻辑,例如简单的保存一下
m_size = pSize;
},
enumerable: true
}
};
}()));
把Square定义的那段代码换成上面这段,就有点样子了。
var Shape = { twoDimensional: true, color: 'Red'};
var square = Object.create(Shape);
Object.defineProperty(square, 'type', {
value : 'square',
enumerable : true,
writable: true
});
square.type = 'rectangle';
alert(square.type);
使用defineProperties方法就与create中的第二个参数一致了,参见:
var Shape = { twoDimensional: true, color: 'Red'};
var square = Object.create(Shape);
Object.defineProperties(square, (function () {
var m_size; return {
// 简单的属性,不包含任何的其他逻辑的属性
type: { value: 'square', enumerable: true, writable: true },
// 复杂一点的属性,包含有一些逻辑的属性
size: {
get: function() { return m_size;},
set: function(pSize) {
// 常见的条件检查
if (pSize > 10) alert('Too large...');
// 其他的处理逻辑,例如简单的保存一下
m_size = pSize;
},
enumerable: true
}
};
}()));
square.type = 'rectangle';
alert(square.type);
square.size = 9;
alert(square.size);
注意defineProperty/defineProperties这两个函数的返回值就是修改后的对象,有时候会使用这个返回值。
var Shape = {
get type() { return this.__type__;},
set type(value) { this.__type__ = value;}
};
var square = Object.create(Shape);
square.type = 'rectangle';
alert(square.type);
简单吧,很简洁,非常强大。
var o = { name: 'frank'};
Object.defineProperties(o, {
p1: { value: 1, enumerable: true },
p2: { value: 2, enumerable: false }
});
alert(Object.keys(o));
alert(Object.getOwnPropertyNames(o));
注意name这种原始的属性是可枚举的,以前通过for/in结合hasOwnProperty方法才能完成枚举对象自身定义的属性的功能现在直接可以通过遍历keys完成了。
preventExtensions方法禁止对象添加新属性,isExtensible检测对象是否使用了preventExtensions方法。
seal方法禁止对象添加新属性和禁止删除已有属性,isSealed检测对象是否使用了seal方法。
freeze方法禁止对对象做任何修改,不能添加新属性和删除已有属性,也不能修改对象的属性值,isFrozen检测对象是否使用了freeze方法。
看到了吧,一个比一个严格,等到了使用freeze方法的时候,对象完全变成了只读对象,这个在很多场合下还是很有用的。看个简单的例子:
var o = { name: 'frank'};
Object.preventExtensions(o);
o.age = 10;
alert(o.age); //undefined,代表无法添加新属性
Object.seal(o);
delete o.name;
alert(o.name); // 删除不了
Object.freeze(o);
o.name = 'dong';
alert(o.name); // 无法修改
var a = ['a','b','c','b'];
alert(a.indexOf('b')); //
alert(a.indexOf('y')); // -1
alert(a.lastIndexOf('b')); //
2. every/some/forEach/filter/map/reduce/reduceRight
[1, 2, 3].map(function(item, index, arr){
return item * item;
});
// [1, 4, 9]
通过函数的call方法,map方法可以用于字符串。
[].map.call('abc', function (x) { return x.toUpperCase() })
// [ 'A', 'B', 'C' ]
// 或者
'abc'.split('').map(function (x) { return x.toUpperCase() })
// [ 'A', 'B', 'C' ]
forEach方法对所有元素依次执行一个函数,它与map的区别在于不返回新数组,而是对原数组的成员执行某种操作,甚至可能改变原数组的值。
[1, 2, 3].forEach(function(item, index, arr){
console.log("array[" + index + "] = " + item);
});
// array[0] = 1
// array[1] = 2
// array[2] = 3
从上面代码可以看到,map和forEach的参数格式是一样的,都是一个函数。该函数接受三个参数,分别是当前元素、当前元素的位置(从0开始)、整个数组。
var out = [];
[1, 2, 3].map(function(item, index, arr){
this.push(item * item);
}, out);
out // [1, 4, 9]
上面代码表示,如果提供一个数组作为第二个参数,则函数内部的this关键字就指向这个数组。
[1,2,3,4,5].filter(function(item){
return (item>3);
})
// [4,5]
上面代码将大于3的原数组成员,作为一个新数组返回。
[1, 2, 3, 4, 5].filter(function(item, index, arr){
return index % 2 === 0;
});
// [1, 3, 5]
上面代码返回原数组偶数位置的成员组成的新数组。
[1, 2, 3, 4, 5].some(function(item, index, arr){
return item >= 3;
});
// 返回true
上面代码表示,如果存在大于等于3的数组成员,就返回true。
[1, 2, 3, 4, 5].every(function(item, index, arr){
return item >= 3;
});
// 返回false
上面代码表示,只有所有数组成员大于等于3,才返回true。
用来累计的变量(即当前状态)
数组的当前元素
当前元素在数组中的序号(从0开始)
原数组
这四个参数之中,只有前两个是必须的,后两个则是可选的。
[1, 2, 3, 4, 5].reduce(function(x, y){
return x+y;
});
//
上面代码的参数x表示累计变量,默认为0,y则是数组的当前元素。reduce方法依次将每个数组元素加入x,最终返回它们的总和15。
Array.prototype.sum = function (){
return this.reduce(function (partial, value){
return partial + value;
})
};
[3,4,5,6,10].sum()
//
如果要对累计变量指定初值,可以把它放在reduce方法的第二个参数。
[1, 2, 3, 4, 5].reduce(function(x, y){
return x+y;
}, 10);
//
上面代码指定参数x的初值为10,所以数组元素从10开始累加,最终结果为25。
function findLongest(entries) {
return entries.reduce(function (longest, entry) {
return entry.length > longest.length ? entry : longest;
}, '');
}
var names = ['Collis', 'Cyan'];
Array.isArray(names); // true
// 仅仅绑定了this,还需要主动的通过对象去调用
tooltip.show = showText.bind(tooltip);
tooltip.show();
overlay.show = showText.bind(overlay);
overlay.show();
// 直接调用的apply/call形式
showText.call(tooltip);
showText.call(overlay);
Date.now()
// 1364026285194类似的数字
如果需要更精确的时间,可以使用window.performance.now()。它提供页面加载到命令运行时的已经过去的时间,单位是浮点数形式的毫秒。
window.performance.now()
// 21311140.415类似的数字
这一组方法可用于生成一种唯一的id标识。
alert(new Date().toJSON());
" hello world ".trim()
// "hello world"
JavaScript大杂烩13 - 总结ECMAScript 5新功能的更多相关文章
- ECMAScript es6新功能讲解视频教程
下载链接:https://www.yinxiangit.com/1.html 目录: 01.课程介绍-ECMAScript 新功能.mp402.块的作用域-let.mp403.恒量-const.mp4 ...
- Python Twisted系列教程13:使用Deferred新功能实现新客户端
作者:dave@http://krondo.com/deferred-all-the-way-down/ 译者:杨晓伟(采用意译) 你可以从这里从头阅读这个系列. 介绍 回忆下第10部分中的客户端5 ...
- ECMAScript 2016,2017 和 2018 中所有新功能的示例
很难追踪 JavaScript(ECMAScript)中的新功能. 想找到有用的代码示例更加困难. 因此,在本文中,我将介绍 TC39 已完成 ES2016,ES2017 和 ES2018(最终草案) ...
- [转]ECMAScript 2016,2017 和 2018 中所有新功能的示例
很难追踪 JavaScript(ECMAScript)中的新功能. 想找到有用的代码示例更加困难. 因此,在本文中,我将介绍 TC39 已完成 ES2016,ES2017 和 ES2018(最终草案) ...
- 探秘IntelliJ IDEA 13测试版新功能——调试器显示本地变量
IntelliJ IDEA在业界被公认为最好的Java开发平台之一,JetBrains公司将在12月正式发布IntelliJ IDEA 13版本. 现在,小编将和大家一起探秘密IntelliJ IDE ...
- Cobalt Strike 3.13的新功能
Cobalt Strike 3.13现已推出.此版本添加了TCP Beacong,进程参数欺骗,并将Obfuscate和Sleep功能扩展到SMB和TCP Beacons. TCP Beacon Co ...
- Java 17 将要发布,补一下 Java 13 中的新功能
本文章属于Java 新特性教程 系列,已经收录在 Github.com/niumoo/JavaNotes ,点个赞,不迷路. 自从 Oracle 调整了 Java 的版本发布节奏之后,Java 版本发 ...
- 超详细 Java 15 新功能介绍
点赞再看,动力无限.微信搜「程序猿阿朗 」,认认真真写文章. 本文 Github.com/niumoo/JavaNotes 和 未读代码博客 已经收录,有很多知识点和系列文章. Java 15 在 2 ...
- Visual Studio 2017十五项新功能体验
Visual Studio 2017正式已经于2017.3.7号正式发布,选在这一天发布也是为了纪念Visual Studio 二十周年.MVP 2017技术峰会将于这个周末(3.17)在北京举办,由 ...
随机推荐
- vsftpd3.0.3配置
2019.2.18更新 证实可用!!! 原文: 这两天测试在Ubuntu18.04上搭建一个ftp服务器,搜了一下大家都在用vsftpd,于是根据这个大佬的基础教程搭了一个,搭完一切正常,在windo ...
- odoo开发笔记 -- 进入后台调试模式
./odoo-bin shell -d test1 -c /home/odoo/odooshare/odoo.conf ./odoo-bin shell -d 数据库名 -c 指定配置文件
- 自动化测试工具selenium webdirver
看视频学到的,自动化测试工具,可以模拟用户操作,包括输入,点击等操作 新建新文件夹 在命令行执行npm init ,一路回车,把项目先初始化 安装 npm install selenium-web ...
- dart之旅(一)
前言 最近在看 dart 了,本着 "纸上得来终觉浅,绝知此事 markdown" 的原则,准备边学边写,写一个系列,这是第一篇.学习过程中主要是参考 A Tour of the ...
- 【适合公司业务】全网最详细的IDEA里如何正确新建【普通或者Maven】的Java web项目并发布到Tomcat上运行成功【博主强烈推荐】(类似eclipse里同一个workspace下【多个子项目】并存)(图文详解)
不多说,直接上干货! 首先,大家要明确,IDEA.Eclipse和MyEclipse等编辑器之间的新建和运行手法是不一样的. 如果是在Myeclipse里,则是File -> new -> ...
- Spring Security使用报错 No bean named 'springSecurityFilterChain' is defined
今天配置spring security时,运行报出No bean named 'springSecurityFilterChain' is defined错误,报错信息如下 严重: Exception ...
- jquery插入,复制、替换和删除节点
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...
- Vue2.5开发去哪儿网App 详情页面开发
一,banner 图的设计 1. 新建detail的路由 import Detail from '@/pages/detail/Detail' ...... { path: '/detail', na ...
- webpack4打包报错:WARNING in configuration The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults fo
运行命令webpack ./src/main.js ./dist/murenziwei.js后,目录上神马动静都没有,你以为在dist文件夹上会有murenziwei.js吗?毛都没有 警告和错误倒是 ...
- SpringBoot JPA + H2增删改查示例
下面的例子是基于SpringBoot JPA以及H2数据库来实现的,下面就开始搭建项目吧. 首先看下项目的整体结构: 具体操作步骤: 打开IDEA,创建一个新的Spring Initializr项目, ...