【原创】js语言特性编程总纲:对象,函数,事件,异步,原型
参考:
https://segmentfault.com/a/1190000017816152(原型链)
https://segmentfault.com/a/1190000017816134(es6类和继承原理)
https://blog.csdn.net/cc18868876837/article/details/81211729 (彻底搞懂__prop__,constructor,prototype)
js这个语言的核心特点:
1,一切皆为对象
2,事件驱动:每一个dom就是一个发布订阅模式
3,异步:回调函数
4,基于原型的继承
5,函数是万能的
单例编程
1,对象字面量
2,new Function(){}
var o = {} 是 var o = new Object() 的语法糖 var a = [] 是 var a = new Array() 的语法糖 function Foo(){} 相当于 var Foo = new Function(){}
面向对象编程
1,原型继承(nodejs的继承和es6的class)
nodejs的继承
function inherits(ctor, superCtor) { ctor.super_ = superCtor; ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } }); }; function Stream(){ //... } function OutgoingMessage() { Stream.call(this); //... } inherits(OutgoingMessage, Stream); OutgoingMessage.prototype.setTimeout = function(){}
es6的class继承语法糖
//调用方式检测 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } //继承 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } //构造函数的初始化 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
2,js继承的核心原理
function Human(sex='female'){ this.sex=sex; } Human.prototype = { constructor : Human, showSex:function(){ console.log(this.sex); } } function Science(){ Human.call(this,...arguments); } //Science.prototype = Human.prototype;//这种写法是错的,会改变父类的原型对象,因为是引用传递 Science.prototype = new Human(); //应该这样继承,新的对象会把__prop__传递给子类的prototype Science.prototype.constructor = Science; Science.prototype.sayScience = function(){}; console.log(Human.prototype); console.log(Science.prototype); $h = new Science('male'); console.log($h.__proto__ === Science.prototype); console.log($h.__proto__); console.log(Science.prototype);
3,new一个函数发生了什么
1,创建一个对象 2,{}._proto_ = 构造函数.prototype 3,this指向这个对象 4,执行代码即对this赋值 5,返回this
4,原型规则
1.所有引用类型(对象,数组,函数)都具有一个__proto__(隐式原型)属性,是一个普通对象 2.所有的函数都具有prototype(显式原型)属性,也是一个普通对象 3.所有引用类型__proto__值指向它构造函数的prototype 4.获取一个对象的属性时,如果对象本身没有这个属性,则会去他的__proto__对象中去找,如果他的__proto__对象中没有,则会在__proto__的对象的__proto__对象中找,一层一层往上
模块化编程
1,node的模块的原理
参考:
http://nodejs.cn/api/modules.html#modules_the_module_wrapper(模块封装器)
http://nodejs.cn/api/modules.html#modules_exports_shortcut(模块导入和导出)
(function(exports, require, module, __filename, __dirname) { // 模块代码实际存在于此处 }); function require(/* ... */) { const module = { exports: {} }; ((module, exports) => { // 模块代码在这里。 在本例中,定义一个函数。 function someFunc() {} exports = someFunc; // 此时,exports 不再是 module.exports 的快捷方式, // 并且此模块仍然会导出空的默认对象。 module.exports = someFunc; // 此时,该模块现在将导出 someFunc, // 而不是默认对象。 })(module, module.exports); return module.exports; }