面向对象
面向对象 MDN
JavaScript面向对象编程
命名空间
如果你在公司 var a = 1;是要被离职的
因为你不知道 a以前是什么
1 2 3 4 5 6 7 8
| // 全局命名空间 var MYAPP = MYAPP || {}; //等价于 if(MYAPP){ var MYAPP = MYAPP }else{ var MYAPP = {} }
|
代码技巧 先看看表达式的值是什么
1 2 3 4 5 6
| 1 || 2 //1 1 && 2 && 3 //3
0||null||undefined||1 //1
|
重要概念
1 2 3 4 5 6 7 8
| a || b
c && d
//它们的值基本不可能是 true / false //五个falsy值
// 0 NaN '' null undefined
|
1 2 3 4 5 6 7 8 9 10 11 12
| 1 && 0 // 0
1 && 0 && 2 // 0
1 && 0 && console.log(3) //打印3不会执行 会返回 0
1 && 2 && 3 // 3
0 || undefined || null || 1 // 1
0 || undefined || null || 1 || 0 || null // 1
|
回到之前的命名空间写法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| var app = {}//危险代码
if(app){ //app = app 这句可以不写 是废话 } }else{ app = {} }
// 安全写法
var app2 = app2 || {}
if(app2){ app2 = app2 }else{ app2 = {} }
|
this复习
待更新。。。。
new是做啥的
当我们需要100个士兵 就要写100次
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| var 士兵们 = []; var 士兵 ; for(var i=0;i<100;i++){ 士兵 = { ID: i, // 用于区分每个士兵 兵种:"美国大兵", 攻击力:5, 生命值:42, 行走:function(){ /*走俩步的代码*/}, 奔跑:function(){ /*狂奔的代码*/ }, 死亡:function(){ /*Go die*/ }, 攻击:function(){ /*糊他熊脸*/ }, 防御:function(){ /*护脸*/ } } 士兵们.push(士兵) }
|
这样是很耗内存的因为 每个士兵自己都有 这些方法 但这些方法内容是一样的 就会出现500个方法
1 2 3 4 5
| 行走:function(){ /*走俩步的代码*/}, 奔跑:function(){ /*狂奔的代码*/ }, 死亡:function(){ /*Go die*/ }, 攻击:function(){ /*糊他熊脸*/ }, 防御:function(){ /*护脸*/ }
|
士兵共有属性
proto__ __ 这样
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| var 士兵共有属性 = { 兵种:"美国大兵", 攻击力:5, 行走:function(){ /*走俩步的代码*/}, 奔跑:function(){ /*狂奔的代码*/ }, 死亡:function(){ /*Go die*/ }, 攻击:function(){ /*糊他熊脸*/ }, 防御:function(){ /*护脸*/ } }
var 士兵们 = []; var 士兵 ; for(var i=0;i<100;i++){ 士兵 = { ID: i, // 用于区分每个士兵 生命值:42 } /*实际工作中不要这样写__proto__ 不是标准属性*/ 士兵.__proto__ = 士兵共有属性 士兵们.push(士兵) }
|
这样你会感觉士兵和 士兵共有属性很松散
使用函数把 士兵 和 士兵共有属性 包裹起来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| var 士兵共有属性 = { 兵种:"美国大兵", 攻击力:5, 行走:function(){ /*走俩步的代码*/}, 奔跑:function(){ /*狂奔的代码*/ }, 死亡:function(){ /*Go die*/ }, 攻击:function(){ /*糊他熊脸*/ }, 防御:function(){ /*护脸*/ } }
function create士兵(id){ var 士兵 = { ID:i,// 生命值:42 } 士兵.__proto__ = 士兵共有属性 return 士兵 }
//创建士兵 var 士兵们 = []; var 士兵 ; for(var i=0;i<100;i++){ 士兵们.push( create士兵(i) ) }
|
这样 create士兵 和 士兵共有属性还是没太大关联性
把 “士兵的共有属性” 放到 “create士兵” 的属性 里
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| function create士兵(id){ var 士兵 = { ID:i,// 生命值:42 } 士兵.__proto__ = create士兵.士兵共有属性 return 士兵 }
create士兵.士兵共有属性 = { 兵种:"美国大兵", 攻击力:5, 行走:function(){ /*走俩步的代码*/}, 奔跑:function(){ /*狂奔的代码*/ }, 死亡:function(){ /*Go die*/ }, 攻击:function(){ /*糊他熊脸*/ }, 防御:function(){ /*护脸*/ } }
|
JS之父的关怀
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| function 士兵(id){ //step1 //var temp = {} //step2 //this = temp //step3 //this.__proto__ = create士兵.prototype this.ID = id; this.生命值 = 42 //step4 //return this }
士兵.prototype = { constructor:士兵, 兵种:"美国大兵", 攻击力:5, 行走:function(){ /*走俩步的代码*/}, 奔跑:function(){ /*狂奔的代码*/ }, 死亡:function(){ /*Go die*/ }, 攻击:function(){ /*糊他熊脸*/ }, 防御:function(){ /*护脸*/ } }
// 你要做的事情 就是 加个new
var 士兵 = new 士兵(id);
|
原理 new 士兵()之后
- 生成一个临时对象 temp
- 然后用 this指向 这个临时对象 temp
- 然后让this的原型 等于这个函数的prototype
- 而且也不用return 这个事 也帮你做了 帮你返回this
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| var obj =new Object()
自有属性 空 obj.__proto__ === Object.prototype
var array = new Array('a','b','c') 自有属性 0:'a' 1:'b' 2:'c' length:3 array.__proto__ === Array.prototype Array.prototype.__proto__ === Object.prototype
var fn =new Function('x','y','return x+y') 自有属性 length:2 不可见函数体: 'return x+y' fn.__proto__ === Function.prototype
Array is a Function Array = function(){...} Array.__proto__ === Function.prototype
|