随着ES6推出和浏览器的逐渐兼容以及babel等转义工具的普及,ES6更加强大的语法也成了写REACT, AngularJs2,Ionic2等框架成本较低的首选语言。本菜鸡在朋友的推荐下,逐渐的尝试ES6的语法及demo编写,把趟过的坑及学到的东西在此记录,也以此自勉,多读书,多练习。
因为浏览器目前还不能完全跑起ES6的语法,所以那些对新技术着迷的极客们就需要将用ES6写的文件,转换成ES5的语法,而babel就是这样一个工具。根据babel官网上查到的,有二十余种babel的使用方式。包括前端涉及过的babel-cli命令行以及配合Grunt,Gulp,Webpeck等前端自动化工具使用。
我这里用babel-cli工具,先做测试,用babel转化一个简单的ES6文件再说。
npm install --global babel-cli
先全局安装babel-cli工具,再安装preset-2015,这是es5转义的标准,如果你需要转义REACT,也需要安装preset-react
npm install babel-preset-es2015
接下来需要创建一个.babelrc文件(win下创建一个txt然后重命名会提示‘请输入文件名‘,我是在sublime里new file,然后就可以命名.babelrc了),命令行是根据里边的配置来解析ES6文件的,在里边放入如下代码。
{
"presets": ["es2015"]
}
接下来在cmd或者git bash里边‘cd’到你对于的文件夹目录,执行babel < 待转义文件>,比如我这里是source.js,转义完保存在transferred.js
babel source.js
或者
babel source.js --out-file transferred.js
就可以得到转义成ES5的文件了。
这段时间一直在看es6,之前在angularjs里见过这种promise的写法,当时在js里没见过,在ngcordova的插件的api中见过,当时只是比猫画虎的用用,效果ok,就过去了,es6中有专门的一章,在此记录,以备忘。
promise出现就是为了解决callback hell(回调噩梦),让我们较为优雅的链式调用,走完第一步走第二步。现在的主流浏览器都能识别Promise对象。
var promise = new Promise(function(resolve, reject) {
//some code
});
promise.then(function() {
console.log('Resolved.');
});
这里是创建了一个Promise对象,Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由JavaScript引擎提供,不用自己部署。
resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从Pending变为Resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从Pending变为Rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为Resolved时调用,第二个回调函数是Promise对象的状态变为Reject时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。
给个例子:懒加载是多图片网站解决性能问题的较为有效的方法,尤其是瀑布流那种购物网站,这里可以自定义一个方法,实现懒加载,按需加载
<html>
<head>
<title>Promise实现懒加载title>
<meta charset="utf-8" />
head>
<body>
<img src="" id='pic'>
<script>
function loadImageAsync(ID,url) {
return new Promise(function(resolve, reject) {
var image=document.getElementById(ID);//取到页面上的对象,并给其赋值
image.style.width='400px';//初始化一下效果
console.log('promise created')
image.onload = function() {
setTimeout(function(){
resolve(image);//这里可以将dom作为参数传过去
},1000)
};
image.onerror = function() {
reject(new Error('Could not load image at ' + url));
};
image.src = url;
});
}
//函数调用
loadImageAsync('pic','guguji.jpg')//这里guguji.jpg为url路径
.then(function(img){
//加载完毕后可以执行一些效果
img.style.width='300px';
img.style.border='3px solid #abcdef'
console.log('success')
},function(){
console.log('error')
})
script>
body>
html>
解释一下:loadImageAsync函数,return一个Promise对象,其参数是一个函数,先从页面上取到dom对象,然后加载图片完毕后执行函数的第一个对象resolve(它还可以带参数。这里settimeout是为了延时,使效果明显),当执行了resolve以后,就会执行then()里边的第一个函数(包括一个console,和样式变化)。如果resolve失败,执行的reject,就会执行then的第二个函数方法。
bind()方法会创建一个新函数。当这个新函数被调用时,bind()的第一个参数将作为它运行时的 this, 之后的一序列参数将会在传递的实参前传入作为它的参数。
fun.bind(thisArg[, arg1[, arg2[, ...]]])
作用一般有两个:1、创建绑定函数
bind() 最简单的用法是创建一个函数,使这个函数不论怎么调用都有同样的 this 值。JavaScript新手经常犯的一个错误是将一个方法从对象中拿出来,然后再调用,希望方法中的 this 是原来的对象。(比如在回调中传入这个方法。)如果不做特殊处理的话,一般会丢失原来的对象。从原来的函数和原来的对象创建一个绑定函数,则能很漂亮地解决这个问题。
this.x = 9;
var module = {
x: 81,
getX: function() { return this.x; }
};
module.getX(); // 返回 81
var retrieveX = module.getX;
retrieveX(); // 返回 9, 在这种情况下,"this"指向全局作用域
// 创建一个新函数,将"this"绑定到module对象
// 新手可能会被全局的x变量和module里的属性x所迷惑
var boundGetX = retrieveX.bind(module);
boundGetX(); // 返回 81
2、初始参数
bind()的另一个最简单的用法是使一个函数拥有预设的初始参数。这些参数(如果有的话)作为bind()的第二个参数跟在this(或其他对象)后面,之后它们会被插入到目标函数的参数列表的开始位置,传递给绑定函数的参数会跟在它们的后面。
function calcFun(){
//计算函数,把参数加起来而已
var arr=Array.prototype.slice.apply(arguments);
var result=0;
arr.map(function(value,key){
if(value!==undefined){
result+=value;
}
})
console.log(result)
}
var list= calcFun.bind(undefined, 10);
var list2 = list(); // 参数为[10]
var list3 = list(1, 2, 3); // 参数为[10, 1, 2, 3]
3、配合 setTimeout
在默认情况下,使用 window.setTimeout() 时,this 关键字会指向 window (或全局)对象。当使用类的方法时,需要 this 引用类的实例,你可能需要显式地把 this 绑定到回调函数以便继续使用实例。
function LateBloomer() {
this.petalCount = Math.ceil(Math.random() * 12) + 1;
}
// Declare bloom after a delay of 1 second
LateBloomer.prototype.bloom = function() {
window.setTimeout(this.declare.bind(this), 1000);
};
LateBloomer.prototype.declare = function() {
console.log('I am a beautiful flower with ' +
this.petalCount + ' petals!');
};
var flower = new LateBloomer();
flower.bloom(); // 一秒钟后, 调用'declare'方法