Open violet0sea opened 6 years ago
Arrow Function(=>),为什么要引入它呢? 主要是为了解决原本this在function里的指向,首先需要了解this的指向(4种),其中有一种情况是函数只是通过正常的形式调用时,this指向Global对象(严格模式下是undefined),由于this指向带来的困扰,曾今的方式是通过绑定this或者将this指向that等等之类的方式保留this的引用。但是引入=>函数后,直接就将箭头函数里的this绑定在了当前环境的this下,这也是react通常绑定this的方式;
this binding is not dynamic, but is instead lexical => is about lexical binding of this, arguments, and super 如果声明了=>函数,外层没有父级的函数,在箭头函数里直接使用arguments会报错,只有存在父级函数时,才正确,这是因为this, arguments and super都是绑定在里surrounding environment
Javascript里的new操作符实现方式
代码实现:
function NewOperator(func) {
let obj = {}, res;
const args = [].slice.call(arguments, 1);
// obj.__proto__ = func.prototype; 性能不好
// Object.setPrototypeof(obj, func.prototype); 依然性能不佳
obj = Object.create(func.prototype);
res = func.apply(obj, args);
// if((Object(res) === res) && res !== null) {
// return res;
// }
if(res instanceof Object) {
return res;
}
return obj;
}
function Person(name) {
this.name = name;
}
const p1 = NewOperator(Person, 'lemon');
function Student(name) {
this.name = name;
return {};
}
const p2 = NewOperator(Student, 'orange');
this binding 4 ways and arrow function key point: call-site precedence
1.default binding: standalone function invocation
function foo() {
console.log(this) // undefined(strict mode) | global
}
foo();
2.implicit binding: have a context object, which means oject methods
let obj = {
run: foo
};
obj.run() // refer to obj
3. explicit binding Function has call(...) and apply(...) and bind(...)
let boundFun = fun.bind(context);
boundFun();
4.new binding
function foo(a) {
this.a = a;
}
let bar = new foo(10);
bar.a // 10
function foo() { console.log(this.a); }
var a = 2; // let and const did not give window the property foo.call(null) // maybe it is better to use Θ = Object.create(null) (DMZ object) to create an empty object, foo.call(Θ)
Hash 路由 当url的hash路由发生变化时可以监听hashchange事件来响应
export class HashRouter {
constructor() {
this.routes = {}; // 存放不同hash对应的cb
this.currentUrl = '';
}
route(path, callback = noop) {
this.routes[path] = callback;
}
updateView() {
const hashString = location.hash.slice(1) || '/';
let options = {};
if(hashString === '/') {
this.currentUrl = hashString;
} else {
const hashList = hashString.split('/').filter(d => d !== '');
this.currentUrl = '/' + hashList[0];
options.id = hashList[1] || '';
}
const cb = this.routes[this.currentUrl];
if(typeof cb === 'function') {
cb(options);
}
}
init() {
window.addEventListener('load', this.updateView.bind(this), false);
window.addEventListener('hashchange', this.updateView.bind(this), false);
}
}
export class BrowserRouter {
constructor() {
this.routes = {};
this.currentUrl = '';
}
route(path, callback = noop) {
this.routes[path] = callback;
}
updateView(url) {
this.currentUrl = url;
const cb = this.routes[this.currentUrl];
if(typeof cb === 'function') {
cb();
}
}
bindLink() {
const allLinks = document.querySelectorAll('a[data-href]');
for(let i =0; i < allLinks.length; i++) {
const current = allLinks[i];
current.addEventListener('click', e => {
e.preventDefault();
const url = current.getAttribute('data-href');
history.pushState({}, null, url);
this.uodateView(url);
}, false);
}
}
init() {
this.bindLink();
window.addEventListener('popstate', e => {
this.updateView(window.location.pathname);
});
window.addEventListener('load', () => this.updateView('/'), false);
}
}
Promise读书笔记 在Promise出现之前,一直都是使用回调函数来处理异步操作;直到Promise出现,规范了处理规则,按照统一的接口来编写
var promise = getAsyncPromise("file.txt");
promise.then(result => {
// TODO handle data
}).catch(err => {
// TODO handle error
});
对比node中一些文件读取将error作为第一个参数,这种方式更加规范;
规范后的优势:可以形成基于接口的各种各样的异步处理模式(将复杂的异步处理模式化),Promise.all 和 Promise.race就是典型的处理模式
使用new Promise实例化的promise对象有以下三个状态:
promise对象的状态从Pending转换为Fulfilled或者Rejected之后,这个对象的状态就不会再发生改变
注意: promise的状态都是内部定义的,没有公开的api进行访问
以实现一个get请求为例
function getUrl(url) {
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function() {
if(xhr.status === 200) {
resolve(xhr.responseText);
} else {
reject(new Error(xhr.statusText));
}
};
xhr.onerror = function() {
reject(new Error(xhr.statusText));
};
xhr.send();
});
}
Promise.resolve 直接产生一个Fulfilled状态的promise对象
Promise.resolve(100).then(val => console.log(val));
Thenable概念 Promise.resolve方法另外一个作用就是将thenable对象转换为promise对象,thenable指的是一个具有.then方法的对象
对于构造函数,有这么一个问题: 如果一个构造函数没有使用new运算符,如何在构造函数内部改造使其实现和new一样的效果?