一:简述

  

  当初学编程一看到什么什么模式就比较头晕,不过本文我们通过简单的示例代码来说一下js 对象这个话题 ,来看下如何理解这个原型模式。

二:理解对象

    

  1.简单对象

 

  js对象中没有java、C#等类的概念。但是在js中 一切皆对象嘛 我们可以这么写一个实例

 1 <!DOCTYPE html>
 2 <html xmlns="http://www.w3.org/1999/xhtml">
 3 <head>
 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 5     <title></title>
 6 </head>
 7 <body>
 8 
 9     <script>
10         //创建一个对象
11         var person = new Object();
12         //声明属性
13         person.name = 'hello';
14         person.age = 29;
15         person.job = 'Software Engineer';
16         //声明方法
17         person.sayName = function () {
18             alert(this.name);
19         }
20     </script>
21 </body>
22 </html>

是不是很像一个class。但这是早期js创建对象的写法,后来出现了对象字面量的写法 简化了上面的写法

 

  2.对象字面量

 

  我们来改进上面的写法  

 1 var person = {
 2             //属性
 3             name: 'hello',
 4             age: 29,
 5             job: 'Software Engineer',
 6             //声明方法
 7             sayName: function () {
 8                 alert(this.name);
 9             }
10         }

是不是简化了很多,但是上面两种创建的对象如果创建多了会产生大量重复代码 ,所以也就出现了以下第三种模式(又是模式....)

  

  3.工厂模式

  

 1 <!DOCTYPE html>
 2 <html xmlns="http://www.w3.org/1999/xhtml">
 3 <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 5     <title></title>
 6 </head>
 7 <body>
 8 
 9     <script>
10         //用函数来包装
11         function createPerson() {
12             var person = new Object();
13             //声明属性
14             person.name = 'hello';
15             person.age = 29;
16             person.job = 'Software Engineer';
17             //声明方法
18             person.sayName = function () {
19                 alert(this.name);
20             }
21             return person;
22         }
23         //调
24         var person1 = createPerson('tom', 21, 'baidu');
25         var person2 = createPerson('tony', 31, 'tencent');
26     </script>
27 </body>
28 </html>

工厂就是把东西加工、包装成一个对象。 其实我们大多数的写法也就是这么个模式 。但是这样我们怎么知道这个对象的类型呢 ?随着js发展又出来一个新模式

  

  4.构造函数模式

  

 1 <!DOCTYPE html>
 2 <html xmlns="http://www.w3.org/1999/xhtml">
 3 <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 5     <title></title>
 6 </head>
 7 <body>
 8 
 9     <script>
10        
11 
12         function Person(name,age,job) {
13             this.name = name;
14             this.age = age;
15             this.job = job;
16             this.sayName = function () {
17                 alert(this.name);
18             }
19         }
20 
21         var pserson1 = new Person('tom', 21, 'baidu');
22         var pserson2= new Person('tony', 31, 'tencent');
23     </script>
24 </body>
25 </html>

  看着是不是跟对象字面量很像。这个模式跟工厂模式对比来看 

    a.没有显示的创建对象

    b.直接将属性和方法赋值给了this对象

    c.没有return

    d.执行构造函数中的代码(在Person新对象中添加属性和方法)

         

  console.info(person1.constructor == Person);//true
  console.info(person1.constructor == Person);//true

 

  对象的constructor属性 是用来标识对象类型的 ,可以将他的实例标识为一种特定的类型

 

  说说这个特殊的函数--构造函数 ,它跟函数的唯一区别就是调用的方式不同(有啥不同啊。。)

  只要是能通过new操作符来调用的函数就可以作为构造函数。(没new的就是普通函数呗O(∩_∩)O)

   

 //我是构造函数
  var pserson1 = new Person('tom', 21, 'baidu');
  //我是普通函数
  person('tony', 31, 'tencent');

构造函数模式也有自己的问题。每个方法都要在每个实例上重新创建一遍。

构造函数的另一种定义:  

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
</head>
<body> 
    <script> 
        function Person(name,age,job) {
            this.name = name;
            this.age = age;
            this.job = job;
            //第一种写法
            this.sayName = function () {
                alert(this.name);
            }
            //第二种写法
            this.sayName = new Function("alert(this.name)")
        }
         
    </script>
</body>
</html>

这样就可以看出person1.sayName 不等于person2.sayName了  因为不同实例的同名函数是不相等的

但是我们可以这么写:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
</head>
<body> 
    <script> 
        function Person(name,age,job) {
            this.name = name;
            this.age = age;
            this.job = job; 
            this.sayName = sayName
        }
        function sayName() {
            alert(this.name);
        }
    </script>
</body>
</html>

但是这样虽然是函数指向相同了  但是方法多了 就没有封装性可言了 。

  

  5.原型模式

 

  我们每个函数都有一个prototype(原型)属性。它是构造函数中(就是new的函数)自动创建的对象实例的原型对象 (就是一new就有了)

好处:可以让所有对象实例共享它包含的属性和方法(可以直接添)如下

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
</head>
<body> 
    <script> 
        //声明一个空函数(首字母大写)
        function Person() {

        }
     //添加属性和方法 Person.prototype.name
= "tony"; Person.prototype.age=29; Person.prototype.job = 'baidu'; Person.prototype.sayName = function () { alert(this.name); } var person1 = new Person(); person1.sayName();//baidu var person2 = new Person(); person2.sayName();//baidu alert(person1.sayName == person2.sayName);//true </script> </body> </html>

因为新对象的属性和方法都是共享的,所以person1和person2都是访问的同一个sayName函数 

  a.理解原型对象:

  上面说到只要创建一个函数就会自动创建一个prototype属性,这个属性指向的就是函数的原型对象

  Person.prototype.constructor就是Person 

  

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
</head>
<body> 
    <script> 
        //声明一个函数(首字母大写)
        function Person() {

        }
        Person.prototype.name = "tony";
        Person.prototype.age=29;
        Person.prototype.job = 'baidu';
        Person.prototype.sayName = function () {
            alert(this.name);
        } 
        var person1 = new Person();
        console.info(person1);
    </script>
</body>
</html>
View Code

相关文章:

  • 2021-07-16
  • 2022-12-23
  • 2021-12-20
  • 2021-12-24
  • 2021-10-11
  • 2022-12-23
  • 2021-08-23
猜你喜欢
  • 2022-12-23
  • 2021-04-23
  • 2022-01-01
  • 2021-06-06
  • 2022-03-03
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案