ambition888 / blog

Teach Yourself Programming in Ten Years
MIT License
1 stars 0 forks source link

JavaScript 闭包 #2

Open ambition888 opened 5 years ago

ambition888 commented 5 years ago

JavasScript 的闭包的原理,分析。都已经很多了。

相关的知识点有:
闭包,作用域,作用域链 也会一起参与的有:
原型,原型链,event loop

来两道题热热身

var name = "The Window";
var object = {
  name : "My Object",
  getNameFunc : function(){
    return function() { return this.name; };
  }
};
console.log(object.getNameFunc()());

闭包相关的应用与周边

函数式编程

函数式编程是个很大的话题。这里略过。 常见的库都能和函数式不多不少扯上点边: lodash, jQuery, react, rxjs

装饰器 ( Decorator )

react 应用会经常用到数据流的库,例如 react-reduxmobx-react 就跟这能扯上关系了。

// the code is from https://medium.com/fraight/react-redux-decorators-8b38f3b9ef2f
import React from 'react'
import { connect } from 'react-redux'

const mapStateToProps = (state) => {
  return { users: state.users }; 
}

const mapDispatchToProps = (dispatch, ownProps) {
  return {
    getUser(id) {
      dispatch(ownProps.getUser(id)) 
    }
  }
}

@connect(mapStateToProps, mapDispatchToProps)
export default class MyFancyComponent extends React.Component {
 // react things in here 
}

至今,Babel7 已经出了自家的 Decorators 的实现。7.1.0 Released: Decorators, Private Static Fields
当然,TypeScript 之前也有它的装饰器实现,未来理论上是会向社区靠拢。

串联知识点

Decorator( 该语法特征与使用场景 )
Object.defineProperty( 社区很多 Vue 的分析与 mini 库 )
Proxy( Vue 3.0 使用了 Proxy 作为底层的方案,为什么这么选型。以及选型前后的优缺 )

JavaScript 实现 Private 的几种方案

  1. 社区的#标识符提案
    Babel7 实现了 private instance methods 7.2.0 Released: Private Instance Methods

  2. 基于约定。例如: _为开头

    class Animal {
    constructor() {
    this._notPublicProperty = 2
    }
    _notPublicMethod () {
    return this._notPublicProperty
    }
    }
  3. Typescript 的 public, private, and protected ts 的 private 看似没有做有效的操作。应该是为了编译期进行校验操作。

直接放文档:
Typescript - Classes Typescript - 代码编译前后对比

  1. ES5基于闭包
    
    function  Animal() {
    }

Animal.prototype = (function () { var self = this; var _notPublicProperty = 2; function _notPublicMethod() { return _notPublicProperty; }

return { constructor: Animal, getNotPublicProperty: function() { return _notPublicMethod.call(this) } } }())

var dog = new Animal() console.log(dog.getNotPublicProperty()); // 2 console.log(dog._notPublicMethod()); // ReferenceError: _notPublicProperty is not defined


5. Symbol

Symbol是一个全局函数,每调用一次就会产生一个唯一的字符串

const _notPublicMethod = Symbol() const _notPublicProperty = Symbol() class Animal { constructor() { this[_notPublicProperty] = 2; } [_notPublicMethod]() { return this[_notPublicProperty]; // 必须用中括号 } getNotPublicProperty() { return this[_notPublicMethod]() } }

var dog = new Animal()

console.log(dog.getNotPublicProperty()); // 2 console.log(dog._notPublicMethod()); // ReferenceError: _notPublicProperty is not defined

每次都要创建一个Symbol还是不那么完美,但是已经不错了。

6. WeakMap
Map和WeakMap都是ES6新引入的数据结构。  
Map和Object类似,都是hash结构。Object的键只能是字符串,而Map打破了这一限制,键可以是任意数据类型,而WeakMap比Map要弱一点,键只能是对象;且WeakMap的键名所指向的对象,不计入垃圾回收机制。  
主要的思路是,在类的级别上创建一个 WeakMap 容器,用于存储各个实例的私有成员。  

const store = new WeakMap()

class Animal { constructor() { var self = this;

function _notPublicMethod() {
  return store.get(this)._notPublicProperty
}

store.set(this,{
  _notPublicProperty: 2,
  _notPublicMethod: _notPublicMethod.bind(self)
})

}

getNotPublicProperty() { return store.get(this)._notPublicMethod } }

var dog = new Animal()

console.log(dog.getNotPublicProperty()); // 2 console.log(dog._notPublicMethod()); // ReferenceError: _notPublicProperty is not defined



### 编写或使用 JavaScript SDK
哪些情况你应该设计SDK?   
1. 嵌入的widgets - 在第三方网页上嵌入的交互应用(Disqus, Google Maps, Facebook Widget) 
2. 分析和度量 - 收集用户信息,了解访客和网站交互的方式 (GA, Flurry, Mixpanel)。 
3. 封装网络服务 - 开发调用外部网站服务的客户端应用. (Facebook Graph API) 

例如: 广告SDK, Google Analytics 打点我们会用得比较多。我们要填个 id 进行 init 之后,剩下的工作就不用开发者担心太多。

### webpack 模块系统
webpack 它是怎么做到让我们如此方便地写 `import` / `export`?  
`__webpack_require_` 是个什么操作。如何兼容了 `CMD` / `AMD` / `UMD` 规范?  
我们打包打了 `vendor` / `lib`, 它是怎么被不同子模块引用的。   
https://medium.com/ag-grid/webpack-tutorial-understanding-how-it-works-f73dfa164f01  
http://imweb.io/topic/5a4cce35a192c3b460fce39b  
http://imweb.io/topic/5a43064fa192c3b460fce360  
https://webpack.js.org/concepts/manifest/#runtime  
https://webpack.js.org/guides/output-management/#the-manifest  

本文有很多资料参考于以下资源。十分感谢。
## 推荐资源  
[MDN - Closures](
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures)  
阮老师的 [学习Javascript闭包(Closure)](http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html) 
《你不知道的 JavaScript 》  

## 参考资源
[JavaScript实现私有成员](https://www.jianshu.com/p/806eacda4c0e)  
[JavaScript SDK 设计指南Script](https://www.aliyun.com/jiaocheng/1010119.html)  
MARPTS commented 5 years ago

good job!

skyline-123 commented 5 years ago

点赞