js面向对象实例讲解

时间:2018-10-10
本文章向大家介绍js面向对象实例讲解,需要的朋友可以参考一下

我是菜鸟,老鸟勿看,纯属笔记,加强记忆,不是教程,没有逻辑,不适合学习使用。

--------------

继承多态等太多概念难以理解,还是从实践中慢慢学吧!争取能大致看懂网上的开源的代码。

--------------

对象的组成:方法和属性

属性关键词:静止的,状态

方法关键词:动态的,过程,处理,带括号

--------------

js中的面向对象不是其他语言那样的面向对象。

 1         <script type="text/javascript">
 2         //定义arr为一个数组(数组也是一个对象实例,所以arr是个对象实例)
 3         var my_arr=[];
 4         //以前变量这样用,var number=10; 
 5         //现在定义属性,arr.number = 10; 就是用“点”即可!
 6         my_arr.number = 10;
 7         //定义对象的方法
 8         my_arr.test = function(){
 9             console.log(this); 
10             //这里this就是这个数组,直接用数组名也可以
11             //alert(my_arr.number);
12             //alert(this.number);
13         }
14         //这样使用方法
15         my_arr.test();
16     </script>
17 
18     

结果是数组有个number属性和test方法,但是数组内容为空,length为0,但是这样alert(my_arr['number']);也可以弹出10

//TODO 以后再研究数组,但是可见,数组的内容是内容,属性和内容不是一回事,内容是数组里面存了啥,属性是这个数组实例有什么属性。如同,一个是汽车里装了谁谁,一个是汽车有车大灯的感觉。

------------

新建一个纯净的对象实例

 1     <script type="text/javascript">
 2         var my_obj = new Object(); //新建一个对象实例my_obj,换成 var my_obj = {}; 也行,一个意思
 3         my_obj.name = '张三'; //加个属性
 4         my_obj.test = function(){ //加个方法
 5             this.test2(); //对象的A方法中用到对象的B方法
 6         }
 7         my_obj.test2 = function(){
 8             console.log(this.name);
 9         }
10         my_obj.test(); //使用
11     </script>

 对象中思考变量作用域的问题

以前学到变量作用域,都是函数和变量,现在加入对象,看看是怎么回事

1     <script type="text/javascript">
2         console.log(my_obj); // 显示undefined,说明解析器中和其他类型一样,根据var,先放个undefined再说
3         var my_obj = {};
4         console.log(my_obj); // 显示 Object {}
5         my_obj.name = '张三';
6         console.log(my_obj); // 显示Object {name:"张三"}
7     </script>

其实可以这样理解,js解析器,预解析,根据var找到了my_obj,赋值undefined,如果放到不用对象的时候,出个name,需要var name一下,这里由于对象var了,对象下各个目前未定义的属性就相当于已经var但没赋值了,一旦测试都是undefined。第4行,由于还没有赋予name属性,如果查看my_obj.name的话,就是undefined,而第5行赋值,第6行再看,就是“张三”了。

1     <script type="text/javascript">
2         var my_obj = {};
3         my_obj.name = '张三';
4         console.log(my_obj.test); //undefined
5         my_obj.test(); //浏览器提示出错,说test不是一个函数。可见my_obj.test = function(){...} 只是一个赋值,并没有因为是function,就扔到预解析仓库中
6         my_obj.test = function(){
7             console.log(this.name);
8         }
9     </script>
1     <script type="text/javascript">
2         var my_obj = {};
3         my_obj.name = '张三';        
4         my_obj.test = xxx;
5         my_obj.test(); //这样写是可以执行的,因为函数xxx扔到预解析仓库了,上一行又赋予test这个函数了,显示张三
6         function xxx(){
7             console.log(this.name);
8         }
9     </script>
<script type="text/javascript">
        var my_obj = {};
        my_obj.name = '张三';        
        my_obj.test = function xxx(){
            console.log(this.name);
        };
        my_obj.test(); // 正常运行
    
        
    </script>
 1 <script type="text/javascript">
 2         var my_obj = {};
 3         my_obj.name = '张三';        
 4         my_obj.test = function xxx(){
 5             console.log(this.name);
 6         };
 7         xxx(); //浏览器报错,火狐认为,xxx未定义,也就是说,在等号后面的函数不会被预解析,这里不求预解析,连解析都没有
 8     </script>
 1     <script type="text/javascript">
 2         var my_obj = {
 3             name : "张三",
 4             test : function(){
 5                 //对象也是个变量作用域,这里面是可以使用对象外面的函数的
 6                 //console.log(name); 不可以这样用,不能因为name和test平级,就不加this,属性名和变量是不同的,要加上对象名才能用
 7                 console.log(this.name); //console.log(my_obj.name); 这样也行
 8             }
 9         };
10         my_obj.test(); //显示张三
11         console.log(my_obj.name); //想使用对象的属性,就要加对象名
12         
13     </script>

-----------------------

这里新建对象不够灵活,如果要建的对象名不是张三呢,而是好几个,张三,李四,王二,麻子等很多人,那么就要用到工厂方式

还按照上面的方式就是如下代码

 1         <script type="text/javascript">
 2             var my_obj1 = {
 3                 name: "张三",
 4                 test: function() {
 5                     console.log(this.name); //如果是console.log(my_obj2.name); 将显示李四,也就是用到了其他对象的属性。
 6                 }
 7             };
 8             
 9             var my_obj2 = {
10                 name : "李四",
11                 test : function(){
12                     console.log(this.name);
13                 }
14             }
15             my_obj1.test(); //显示张三
16             my_obj2.test(); //显示李四
17         </script>

js并不是其他语言那样的面向对象,这里的对象,其实是其他语言中 对象实例的意思。

上面代码怎么精简呢,共同部分用一个函数来生成即可,也就是所谓的工厂模式,如下

 1         <script type="text/javascript">
 2             function CreatePerson(name){ //这个function就相当于一个生产对象的工厂
 3                 var obj = new Object();
 4                 obj.name = name;
 5                 obj.test = function() {
 6                     console.log(this.name);
 7                 }
 8                 return obj;
 9             }
10             
11             var my_obj1 = CreatePerson('张三'); //开始生产了
12             var my_obj2 = CreatePerson('李四');
13             my_obj1.test();//使用工厂生产出来的对象
14             my_obj2.test();
15         </script>

在js中,用new去调用一个函数的话,这个函数中的this就是创建出来的对象,而且函数的返回值直接就是this  隐式返回

难以理解这句吧,就是js规定的,函数加new, 函数中的this就是对象实例本身,并且函数返回该对象实例(不用你操作了,js帮你搞定)。

1         <script type="text/javascript">
2             function CreatePerson(name){
3                 this.name = name;
4                 console.log(this); //打印出的this就是张三  这里就相当于js帮你做了 var my_obj1 = new Object(); 最后return my_obj1;
5             }
6             var my_obj1 = new CreatePerson('张三');
7             console.log(my_obj1); //打印出的my_obj1就是张三
8         </script>

这样调用 

var my_obj1 = new CreatePerson('张三'); 是不是很像  var date = new Date();
 1         <script type="text/javascript">
 2             function CreatePerson(name){
 3                 this.name = name;
 4                 this.test = function(){
 5                     console.log(this.name);
 6                 }
 7             }
 8             
 9             var my_obj1 = new CreatePerson('张三');
10             my_obj1.test();
11         </script>