0%

js的面向对象总结

2017年8月18日 下午3:12

阅读方式:

  1. 一定要结合例子去看
  2. Javascript相关知识 - 简书这个链接是我的主要参考的(熟练的看懂)
  3. 汇总的一个js笔记,有很多的文章JavaScript学习笔记 - 专题 - 简书可以后续的学
  4. 零基础打造自己的 js 类库

js中比较有特点的理解—–语法层

  1. 函数
    1. 函数也是一种类型,那么函数名其实就是一个变量,
    2. 同时,函数也可以当成一个对象,在函数中可以使用this指向本身
    3. 有哪些部分
      1. 属性:需要通过对象来调用
      2. 方法:需要通过对象来调用执行
      3. 过程:当函数作为对象new事件发生时,其中的过程会执行
  2. js的运行机制:定义和执行时不同的(读两次),c语言中遍读遍执行
  3. 闭包:函数中的函数,它的最大用处有两个,
    1. 一个是前面提到的可以读取函数内部的变量,
    2. 另一个就是让这些变量的值始终保持在内存中。有一部分static的作用
    3. javascript深入理解js闭包_javascript技巧_脚本之家中的闭包用途
  4. 作用域链
    1. 其实就是一个如何找变量的过程,和c一样,都是从内向外找。程序是一个俄罗斯套娃
  5. json是js中实现面向对象的方式。也就说,js和PHP一样,面向过程和面向对象都可以
    1. Json可以理解为数组
    2. 也可以理解为只带有变量的对象
  6. var参考:javascript定义全局变量的时候有var和没有var的区别 - CSDN博客
    1. 是局部变量,不带时时全局变量
  7. js数组
    1. 像是c++中的stl
    2. Javascript Array数组初探 - 简书
  8. call方法和apply方法:参考:js之this,call,apply用法
    1. 如果我们调用函数的时候,想让函数里的 this 代表别的对象,而不是当前函数的对象。有什么办法呢?那就只好使用call和apply了
    2. 都知道call的用法了,apply其实是一个意思。只不过是调用参数的形式不一样罢了。
    3. call是一个一个调用参数,而apply是调用一个数组。
  9. 对象原型:参考Javascript相关知识 - 简书
    1. 所有的对象都有一个原型对象,所有的对象都继承原型对象的属性。
  10. 原型链:参考:Javascript相关知识 - 简书
    1. 实现:Man.prototype = new Human();// Man的原型指向了Human
    2. 作用:
      1. 指定两个函数(对象)之间的继承关系
      2. 解决每个实例中的每个方法都独自占据一定的内存
    3. 缺点:
      1. 无法传参给超类,方法不能共享()
      2. [在JavaScript的原型链继承方式中,为什么子类在调用父类的构造函数时不能传参数](https://zhidao.baidu.com/question/467325883.html)
      3. 对象(实例)才是属性的拥有者。理解了这句话说明懂了
  11. 对象冒充:参考:Javascript相关知识 - 简书
    1. 实现:使用call方法
    2. 理解:给一个已有属性和方法的函数(对象)换一个名字
    3. 作用
      1. 解决继承中向超类传参的问题
    4. a.call(b,“abc”,123) a,b 是两个对象 “abc” 123是两个变量
  12. 构造函数
    1. 函数首字母大写就是构造函数
  13. 继承
    1. js的面向对象和java的思想就不一样,java是自顶向下的,而js更加随意,给人的感觉是一点点扩展下来的,他的结构并不是一开始就想好的。
    2. js实现继承的方法主要依靠三个点:
      1. 原型链:可以继承属性,但无法传参给超类,方法不能共享(原型会被打断)
      2. 对象冒充:通过call的方式将自己假装成父类
      3. 闭包(函数中的函数)
  14. 关于js中循环带有触发的闭包的理解:参考:JS之经典for循环闭包问题解决方法 - CSDN博客
    1. 这个最本质的原因是js是一个像Android一样,是一个有状态的语言,体现上js是可以写触发的
    2. 这就导致一个程序中其实存在两部分:1:顺序执行的2:等待执行的
    3. 当等待执行的唤醒时,程序中的环境可能已经变了,并不是他睡觉时的那个状态了。
    4. 解决办法:
      1. 给等待执行的程序专门分配一个内存空间,用来存放他醒来时要使用的变量等———–使用函数包含(闭包)
      2. 把需要的变量先给到另一个地方暂为存放,到时候来拿就行了
  15. 函数定义多种方式 参考:Javascript相关知识 - 简书
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function add1(num1,num2){
    return num1 + num2;
    }

    var add2 = function(num1,num2){
    return num1 + num2;
    }

    var add3 = new Function("num1","num2","return num1 + num2");

    window.console.log("add1 = " + add1(10,20));
    window.console.log("add2 = " + add2(100,200));
    window.console.log("add3 = " + add3(1000,2000));
  16. 对象多种类型参考:Javascript相关知识 - 简书
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    var obj = new Object();
    obj.name = "张三丰";
    alert(obj.name)

    var obj = Object();
    obj.name="zhangsanfeng";
    alert(obj.name);

    var obj = {};
    obj.name = "zhangjunbao";
    alert(obj.name);

    var obj = {
    name:"张三丰",
    age:28,
    add:function(num1,num2){
    return num1 + num2;
    }
    };
    alert(obj.name);
    alert(obj['name']);// 以数组的方式来访问属性,必须有单引号或是双引号
    alert(obj.add(10,20));
  17. 零基础打造自己的 js 类库零基础打造自己的 js 类库(1) - 简书
    1. 学到的知识
      1. 封装不是简单的方法的堆积,要考虑扩展性,客户端的简单操作性,面对需求更改时他的适应性是否够用
      2. 这里不仅仅是是方法的堆积就可以解决的问题,更重要的是一个有一个策略
      3. 最大的一个策略:这个类库给他一个dom对象,他就能返回操作这个dom对象各个属性的方法。要的很少,付出很多。

其他:

  1. 当2,4,6放在一起的时候就会变得很复杂,弄清楚这些仅仅是为了弄清楚js的运行机制。在编程的时候只要保证了,1:全局和局部变量不要同名2:只有多处使用的变量才成为全局变量3:声明变量一定要加上var附上值
  2. 总结:c中也存在类似的作用域链,但是从来都关注,编程的时候更注重的是算法。所以说,关注作用域链时,是从变量的角度进行分析的,但是在实际的编程过程中,只思考那些变量是多处使用的,其他的全部写成局部变量。这样就不用考虑作用域链的问题了 。所以,这个作用域链只能作为一个了解的东西,编程时时没用的。
  3. 今天对于语言来说又有了新的认识
    1. 以前的语言学习主要是侧重于语法层次,其实更重要的还有这么语言它本身所带有的类库。
    2. 他的类库支持,更加决定了他的用途,而语法更加影响程序员的编程思路。

附录:

声明原型链中传参

我认为,不是不能给父类构造函数传参数,而是传的参数最终不能起到作用。举个例子:

1
2
3
4
5
6
7
8
9
function Parents(ln) { this.lastName=ln; } //定义父类构造函数
function Children(fn,ln) { this.firstName=fn; } //定义子类,lastName 继承自父类
//原型链继承,给父类构造函数传入参数,试图用 Children 类构造函数中传入的 ln 初始化 lastName:
Children.prototype=new Parents(this ln);
//尝试建立对象实例:
var child=new Children("Bill","Gates");
//输出结果。很明显,lastNmae 并没有得到想要的值:
alert(child.firstName);//Bill
alert(child.lastName);//Undefine

这说明给父类构造函数传递参数是无效的。原因就在于原型链方式中,调用父类构造函数的代码并不在子类构造函数中,建立对象实例时给的属性值(即子类构造函数的参数)并不能影响到子类调用的父类构造函数。
当然,在继承时可以这样写:

1
Children.prototype=new Parents("Gates");//调用父类构造函数时给固定值

但是,这个固定的属性值必定会影响所有子类的对象实例,相当于子类构造函数“擅作主张”给所有对象实例的属性提前“赋了值”。这样写是不太符合面向对象编程的规则的。

匿名函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 匿名函数赋值给变量
var add = function(){
window.console.log("hhhhhhhhhhhhhhhhhhh");
};
add();


// 自运行 (匿名函数)()
(function(name){
window.console.log(name + "来自于中国。。。。。。。");
})("zhangsanfeng");

// 函数里面放置一个匿名函数
function userInfo (){
return function(){ // 闭包:在一个函数中创建另外一个函数,通过另外一个函数访问这个函数的局部变量
return "userInfo"
}
}

window.console.log(userInfo()());

闭包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function increase(){
var count = 0;
return function(){
count++;
return count;
}
}

window.console.log("count1 = " + increase()());
//这里的increase()()有两个括号:第一步执行increase()定义count=0并返回一个闭包(函数/对象)第二步执行这个闭包count++;
window.console.log("count2 = " + increase()());
window.console.log("count3 = " + increase()());
var f = increase();//f是increase()返回的闭包(函数/对象)
// 闭包的优点也是缺点:闭包作用域里面的局部变量资源不会被立刻销毁,如果使用不当,会造成内存泄漏
window.console.log("count11 = " + f());
window.console.log("count12 = " + f());
window.console.log("count13 = " + f());
//f()表示执行闭包
//两个的区别:increase()()是从头开始执行,每次都会重新定义count,而f()是把闭包拿出来,只执行闭包,count只定义了一次

作者:紫苓
链接:http://www.jianshu.com/p/c7ab5ca23ae8#
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
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
29
30
31
32
33
34
35
36
37
38
function arrCreate(){
var arr = [];
for(var i=0;i<5;i++){
// 匿名函数自我执行
arr[i] = (function(num){
return num;
})(i);
}
return arr;
}

var arr = arrCreate();
for(var i=0;i<5;i++){
window.console.log("arr[" + i + "] = " + arr[i]);
}
//////////////////////////////////////////////////////
function arrCreate(){
var arr = [];
for(var i=0;i<5;i++){
arr[i] = (function(num){
// 局部变量驻留在内存中
return function(){
return num;
};
})(i);
}
return arr;
}

var arr = arrCreate();
for(var i=0;i<5;i++){
window.console.log("arr[" + i + "] = " + arr[i]());
}

作者:紫苓
链接:http://www.jianshu.com/p/c7ab5ca23ae8#
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

这个例子和上一个例子知识点相同