WHB1 / WHB1.github.io.old

blog
0 stars 0 forks source link

JavaScript面向对象 #25

Open WHB1 opened 6 years ago

WHB1 commented 6 years ago

深浅拷贝

网址: http://www.alloyteam.com/2017/08/12978/

WHB1 commented 6 years ago

JavaScript对象

1、定义/创建对象


+ b) 方法2 对象字面量
 var person = {
       name : "KJin",
       age : 18,
       job : ”software Engineer”,
       sayName : function(){
           alert(this.name); 
       }
 }
+ c) 方法3 工厂模式
 function createPerson(name, age, job){
        var o = new Object();
        o.name = name;
        o.age = age;
        o.job = job;
        o.sayName = function(){
              alert(this.name);
        };
        return o;
 }
 var person1 = createPerson("Nicholas", 29, "Software Engineer");
 var person2 = createPerson("Greg", 27, "Doctor");

 工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题(即怎样知道一个对象的类型)

+ d) 方法3 构造函数模式

ECMAScript 中的构造函数可用来创建特定类型的对象 像 Object 和 Array 这样的原生构造函数,在运行时会自动出现在执行环境中。 此外,也可以创建自定义的构造函数,从而定义自定义对象类型的属性和方法。

function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = function(){ alert(this.name); }; } var person1 = new Person("Nicholas", 29, "Software Engineer"); var person2 = new Person("Greg", 27, "Doctor");

person1 和 person2 分别保存着 Person 的一个不同的实例。 这两个对象都有一个 constructor(构造函数)属性,该属性指向 Person, alert(person1.constructor == Person); //true alert(person2.constructor == Person); //true

对象的 constructor 属性最初是用来标识对象类型的 检测对象类型,还是 instanceof 操作符要更可靠一些 alert(person1 instanceof Object); //true alert(person1 instanceof Person); //true alert(person2 instanceof Object); //true alert(person2 instanceof Person); //true person1 和 person2 之所以同时是 Object 的实例,是因为所有对象均继承自 Object

构造函数与工厂模式不同点


+ e) 方法4 原型模式

创建的每个函数都有一个 prototype(原型)属性,这个属性是一个指针,指向一个对象, 而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法 如果按照字面意思来理解,那么 prototype 就是通过调用构造函数而创建的那个对象实例的原型对象。

使用原型对象的好处是可以让所有对象实例共享它所包含的属性和方法 换句话说,不必在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中 如下面的例子所示

function Person(){} Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function(){ alert(this.name); }; var person1 = new Person(); person1.sayName(); //"Nicholas" var person2 = new Person(); person2.sayName(); //"Nicholas" alert(person1.sayName == person2.sayName); //true

我们将 sayName()方法和所有属性直接添加到了 Person 的 prototype 属性中,构造函数变成了空函数。 即使如此,也仍然可以通过调用构造函数来创建新对象,而且新对象还会具有相同的属性和方法

但与构造函数模式不同的是,新对象的这些属性和方法是由所有实例共享的。 换句话说,person1 和 person2 访问的都是同一组属性和同一个 sayName()函数

--------1、理解原型对象-----------


-------

### 2、对象数据属性

+   **Configurable**:表示能否通过 delete 删除属性从而重新定义属性,  
                               能否修改属性的特性,或者能否把属性修改为访问器属性  
+   **Enumerable**:表示能否通过 for-in 循环返回属性
+   **Writable**:表示能否修改属性的值
+   **Value**:包含这个属性的数据值。读取属性值的时候,从这个位置读;  
                   写入属性值的时候,把新值保存在这个位置。  
                   这个特性的默认值为 undefined

#### 对象数据属性与声明对象方式关系

| 方式 | 创建object的实例  |  对象字面量 |
|------|---------------|-------------|
| **Configurable**| true  |  true   |
| **Enumerable**| true    |  true  |
| **Writable**| true   |  true   |
| **Value**| 特定值  |  特定值 |

####  Object.defineProperty()方法

+   此方法作用:要修改属性默认的特性
  var person = {};
  Object.defineProperty(person, "name", {
        writable: false,
        value: "Nicholas"
  });
  alert(person.name); //"Nicholas"
  person.name = "Greg";
  alert(person.name); //"Nicholas"

  var person = {};
  Object.defineProperty(person, "name", {
        configurable: false,
        value: "Nicholas"
  });
  alert(person.name); //"Nicholas"
  delete person.name;
  alert(person.name); //"Nicholas"

  一旦把属性定义为不可配置的,就不能再把它变回可配置了

  var person = {};
  Object.defineProperty(person, "name", {
         configurable: false,
         value: "Nicholas"
  });
  //抛出错误
 Object.defineProperty(person, "name", {
         configurable: true,
         value: "Nicholas"
  });

 在调用 Object.defineProperty()方法时, 如果不指定,  configurable、 enumerable 和writable 特性的默认值都是 false。


### 3、对象访问器属性
访问器属性不包含数据值;  
它们包含一对儿 getter 和 setter 函数(不过,这两个函数都不是必需的)。
在读取访问器属性时,会调用 getter 函数,这个函数负责返回有效的值;
在写入访问器属性时,会调用setter 函数并传入新值,这个函数负责决定如何处理数据。
访问器属性有如下 4 个特性。

+   **Configurable**:表示能否通过 delete 删除属性从而重新定义属性,
能否修改属性的特性,
或者能否把属性修改为数据属性。
对于直接在对象上定义的属性,这个特性的默认值为true。
+   **Enumerable**:表示能否通过 for-in 循环返回属性。
对于直接在对象上定义的属性,这个特性的默认值为 true。
+   **Get**:在读取属性时调用的函数。默认值为 undefined。
+   **Set**:在写入属性时调用的函数。默认值为 undefined。

**注意:**访问器属性不能直接定义,必须使用 Object.defineProperty()来定义
WHB1 commented 6 years ago

JavaScript继承