zoukankan      html  css  js  c++  java
  • JavaScript(15):对象和prototype继承

    一、JavaScript 对象定义

    所有 JavaScript 值,除了原始值,都是对象。

    JavaScript 原始值

    原始值指的是没有属性或方法的值。原始数据类型指的是拥有原始值的数据。

    JavaScript 定义了 5 种原始数据类型:

    • string
    • number
    • boolean
    • null
    • undefined

    原始值是一成不变的(它们是硬编码的,因此不能改变)。

    假设 x = 3.14,您能够改变 x 的值。但是您无法改变 3.14 的值。

    JavaScript 对象

    JavaScript 变量能够包含单个的值:

    var person = "Bill Gates";

    对象也是变量,但是对象能够包含很多值。值按照名称 : 值对的形式编写(名称和值以冒号分隔)。

    var person = {firstName:"Bill", lastName:"Gates", age:62, eyeColor:"blue"};

    JavaScript 对象是命名值的集合。

    JavaScript 对象是被称为属性和方法的命名值的容器。

    二、创建 JavaScript 对象

    通过 JavaScript,您能够定义和创建自己的对象。

    有不同的方法来创建对象:

    • 定义和创建单个对象,使用对象文字。
    • 定义和创建单个对象,通过关键词 new。
    • 定义对象构造器,然后创建构造类型的对象。

    在 ECMAScript 5 中,也可以通过函数 Object.create() 来创建对象。

    1、使用对象字面量

    这是创建对象最简答的方法。

    使用对象文字,您可以在一条语句中定义和创建对象。

    对象文字指的是花括号 {} 中的名称:值对(比如 age:62)。

    下面的例子创建带有四个属性的新的 JavaScript 对象:

    var person = {firstName:"Bill", lastName:"Gates", age:62, eyeColor:"blue"};

    空格和折行不重要。对象定义可横跨多行:

    var person = {
        firstName:"Bill",
        lastName:"Gates",
        age:62,
        eyeColor:"blue"
    };

    2、使用 JavaScript 关键词 new

    下面的例子也创建了带有四个属性的新的 JavaScript 对象:

    var person = new Object();
    person.firstName = "Bill";
    person.lastName = "Gates";
    person.age = 50;
    person.eyeColor = "blue";

    上面的两个例子结果是一样的。无需使用 new Object()。

    出于简易性、可读性和执行速度的考虑,请使用第一种创建方法(对象文字方法)。

    注意:对象是易变的:它们通过引用来寻址,而非值。

    如果 person 是一个对象,下面的语句不会创建 person 的副本:

    var x = person;  // 这不会创建 person 的副本。

    对象 x 并非 person 的副本。它就是 person。x 和 person 是同一个对象。

    对 x 的任何改变都将改变 person,因为 x 和 person 是相同的对象。

    var person = {firstName:"Bill", lastName:"Gates", age:62, eyeColor:"blue"}
     
    var x = person;
    x.age = 10;           // 这将同时改变 both x.age 和 person.age

    注释:JavaScript 变量不是易变的。只有 JavaScript 对象如此。

    3、使用JavaScript函数定义一个类型

    function Aclass()
    {
        this.Property = 1;
        this.Method = function()
        {
            alert(1);
        }
    }
    var obj = new Aclass();
    alert(obj.Property);
    obj.Method();

    这个例子演示了通常的在JavaScript中定义一个类型的方法

    三、JavaScript 对象属性

    属性指的是与 JavaScript 对象相关的值。

    属性是任何 JavaScript 对象最重要的部分。

    JavaScript 对象是无序属性的集合。

    属性通常可以被修改、添加和删除,但是某些属性是只读的。

    1、访问 JavaScript 属性

    访问对象属性的语法是:

    bjectName.property           // person.age

    或者:

    objectName["property"]       // person["age"]

    表达式必须计算为属性名。

    person.firstname + " is " + person.age + " years old.";
    person["firstname"] + " is " + person["age"] + " years old.";

    2、JavaScript for...in 循环

    JavaScript for...in 语句遍历对象的属性。

    for...in 循环中的代码块会为每个属性执行一次。

    循环对象的属性:

    var person = {fname:"Bill", lname:"Gates", age:62}; 
    
    for (x in person) {
        txt += person[x];
    }

    3、为实例对象添加或改变属性

    为已有的对象添加新属性很简单:

    myFather.nationality = "English";

    新属性被添加到 myFather。不是 myMother,也不是任何其他 person 对象。

    您不能使用预留词作为属性名(或方法名)。请使用 JavaScript 命名规则。

    4、删除属性

    delete 关键词从对象中删除属性:

    var person = {firstName:"Bill", lastName:"Gates", age:62, eyeColor:"blue"};
    delete person.age;   // 或 delete person["age"];

    delete 关键词会同时删除属性的值和属性本身。

    删除完成后,属性在被添加回来之前是无法使用的。

    delete 操作符被设计用于对象属性。它对变量或函数没有影响。

    delete 操作符不应被用于预定义的 JavaScript 对象属性。这样做会使应用程序崩溃。

    四、JavaScript 对象方法

    JavaScript 方法是能够在对象上执行的动作。

    JavaScript 方法是包含函数定义的属性。

    1、this 关键词

    在 JavaScript 中,被称为 this 的事物,指的是拥有该 JavaScript 代码的对象。

    this 的值,在函数中使用时,是“拥有”该函数的对象。

    请注意 this 并非变量。它是关键词。您无法改变 this 的值。

    2、访问对象方法

    请使用如下语法创建对象方法:

    methodName : function() { 代码行 }

    请通过如下语法来访问对象方法:

    objectName.methodName()

    您通常会把 fullName() 描述为 person 对象的方法,把 fullName 描述为属性。

    fullName 属性在被通过 () 调用后会以函数形式执行。

    此例访问 person 对象的 fullName() 方法

    name = person.fullName();

    如果您访问 fullName 属性时没有使用 (),则将返回函数定义

    name = person.fullName;

    3、为实例对象添加或改变方法

    为已有的对象添加新方法很简单,新方法被添加到 myFather。不是 myMother,也不是任何其他 person 对象。

    myFather.name = function () {
        return this.firstName + " " + this.lastName;
    };

    改变实例对象的已有属性和方法。

    function Aclass()
    {
        this.Property = 1;
        this.Method = function()
        {
            alert(1);
        }
    }
    var obj = new Aclass();
    obj.Property = 2;
    obj.Method = function()
    {
        alert(2);
    }
    alert(obj.Property);
    obj.Method();

    五、JavaScript 访问器(Getter 和 Setter)

    ECMAScript 5 (2009) 引入了 Getter 和 Setter。

    Getter 和 Setter 允许您定义对象访问器(被计算的属性)。

    1、JavaScript Getter(get 关键词)

    本例使用 lang 属性来获取 language 属性的值。

    // 创建对象:
    var person = {
      firstName: "Bill",
      lastName : "Gates",
      language : "en",
      get lang() {
        return this.language;
      }
    };
    
    // 使用 getter 来显示来自对象的数据:
    document.getElementById("demo").innerHTML = person.lang;

    2、JavaScript Setter(set 关键词)

    本例使用 lang 属性来设置 language 属性的值。

    var person = {
      firstName: "Bill",
      lastName : "Gates",
      language : "",
      set lang(lang) {
        this.language = lang;
      }
    };
    
    // 使用 setter 来设置对象属性:
    person.lang = "en";
    
    // 显示来自对象的数据:
    document.getElementById("demo").innerHTML = person.language;

    3、为什么使用 Getter 和 Setter?

    • 它提供了更简洁的语法
    • 它允许属性和方法的语法相同
    • 它可以确保更好的数据质量
    • 有利于后台工作

    一个计数器实例

    var obj = {
      counter : 0,
      get reset() {
        this.counter = 0;
      },
      get increment() {
        this.counter++;
      },
      get decrement() {
        this.counter--;
      },
      set add(value) {
        this.counter += value;
      },
      set subtract(value) {
        this.counter -= value;
      }
    };
    
    // 操作计数器:
    obj.reset;
    obj.add = 5;
    obj.subtract = 1;
    obj.increment;
    obj.decrement;
    Object.defineProperty()

    4、Object.defineProperty() 方法也可用于添加 Getter 和 Setter:

    // 定义对象
    var obj = {counter : 0};
    
    // 定义 setters
    Object.defineProperty(obj, "reset", {
      get : function () {this.counter = 0;}
    });
    Object.defineProperty(obj, "increment", {
      get : function () {this.counter++;}
    });
    Object.defineProperty(obj, "decrement", {
      get : function () {this.counter--;}
    });
    Object.defineProperty(obj, "add", {
      set : function (value) {this.counter += value;}
    });
    Object.defineProperty(obj, "subtract", {
      set : function (value) {this.counter -= value;}
    });
    
    // 操作计数器:
    obj.reset;
    obj.add = 5;
    obj.subtract = 1;
    obj.increment;
    obj.decrement;

    六、JavaScript 对象构造器(构造函数)

    创建一种“对象类型”的方法,是使用对象构造器函数

    在上面的例子中,函数 Person() 就是对象构造器函数

    通过 new 关键词调用构造器函数可以创建相同类型的对象:

    var myFather = new Person("Bill", "Gates", 62, "blue");
    var myMother = new Person("Steve", "Jobs", 56, "green");

    1、为构造函数添加属性

    如需向构造器添加一个新属性,您必须添加到构造器函数:

    function Person(first, last, age, eyecolor) {
        this.firstName = first;
        this.lastName = last;
        this.age = age;
        this.eyeColor = eyecolor;
        this.nationality = "English";
    }

    这样对象属性就可以拥有默认值。

    2、为构造函数添加方法

    必须在构造器函数内部向一个对象添加方法:

    function Person(firstName, lastName, age, eyeColor) {
        this.firstName = firstName;  
        this.lastName = lastName;
        this.age = age;
        this.eyeColor = eyeColor;
        this.changeName = function (name) {
            this.lastName = name;
        };
    }

    changeName() 函数把 name 赋值给 person 的 lastName 属性。

    myMother.changeName("Jobs");

    通过用 myMother 替代 this,JavaScript 可以获知目前处理的哪个 person。

    3、内建 JavaScript 构造函数

    JavaScript 提供用于原始对象的构造器:

    var x1 = new Object();    // 一个新的 Object 对象
    var x2 = new String();    // 一个新的 String 对象
    var x3 = new Number();    // 一个新的 Number 对象
    var x4 = new Boolean();   // 一个新的 Boolean 对象
    var x5 = new Array();     // 一个新的 Array 对象
    var x6 = new RegExp();    // 一个新的 RegExp 对象
    var x7 = new Function();  // 一个新的 Function 对象
    var x8 = new Date();      // 一个新的 Date 对象

    Math() 对象不再此列。Math 是全局对象。new 关键词不可用于 Math。

    正如以上所见,JavaScript 提供原始数据类型字符串、数字和布尔的对象版本。但是并无理由创建复杂的对象。原始值快得多!

    • 请使用对象字面量 {} 代替 new Object()。
    • 请使用字符串字面量 "" 代替 new String()。
    • 请使用数值字面量代替 Number()。
    • 请使用布尔字面量代替 new Boolean()。
    • 请使用数组字面量 [] 代替 new Array()。
    • 请使用模式字面量代替 new RexExp()。
    • 请使用函数表达式 () {} 代替 new Function()。
    var x1 = {};            // 新对象
    var x2 = "";            // 新的原始字符串
    var x3 = 0;             // 新的原始数值
    var x4 = false;         // 新的原始逻辑值
    var x5 = [];            // 新的数组对象
    var x6 = /()/           // 新的正则表达式对象
    var x7 = function(){};  // 新的函数对象

    七、JavaScript 对象原型:prototype

    构造函数创建的属性是实例私有的,原型创建的属性和方法是实例共享的。

    1、在外部使用prototype为类型增加动态属性和方法

    可以在外部使用prototype为自定义的类型添加属性和方法。 但是在外部不能通过prototype改变已有的自定义类型的属性或方法

    function Aclass()
    {
        this.Property = 1;
        this.Method = function()
        {
            alert(1);
        }
    }
    
    Aclass.prototype.Property2 = 2;
    Aclass.prototype.Method2 = function()
    {
        alert(2);
    }
    var obj = new Aclass();
    alert(obj.Property2);
    obj.Method2();

    2、类型的继承(原型链)

    所有 JavaScript 对象都从原型继承属性和方法。

    日期对象继承自 Date.prototype。数组对象继承自 Array.prototype。Person 对象继承自 Person.prototype。Object.prototype 位于原型继承链的顶端,日期对象、数组对象和 Person 对象都继承自 Object.prototype。

    这个例子说明了一个类型如何从另一个类型继承。

    function AClass()
    {
        this.Property = 1;
        this.Method = function()
        {
            alert(1);
        }
    }
    function AClass2()
    {
        this.Property2 = 2;
        this.Method2 = function()
        {
            alert(2);
        }
    }
    AClass2.prototype = new AClass();
    var obj = new AClass2();
    alert(obj.Property);
    obj.Method();
    alert(obj.Property2);
    obj.Method2();

    3、子类如何重写父类的属性或方法

    这个例子说明了子类如何重写父类的属性或方法。

    function AClass()
     {
         this.Property = 1;
         this.Method = function()
         {
             alert(1);
         }
     }
     function AClass2()
     {
         this.Property2 = 2;
         this.Method2 = function()
         {
             alert(2);
         }
     }
     AClass2.prototype = new AClass();
     AClass2.prototype.Property = 3;
     AClass2.prototype.Method = function()
     {
         alert(4);
     }
     var obj = new AClass2();
     alert(obj.Property);
     obj.Method();

    4、原型式继承

    这种方法并没有使用严格意义的构造函数,而是借助原型可以基于已有的对象创建新对象,同时还不用创建自定义类型来达到这个目的。

    以下代码是封装在object函数当中的,在使用的时候直接使用object()

    function object (o)//这个o相当于父对象实例
    {
            function F(){}//这个F相当子对象
            F.prototype=o;//继承
            return new F();//实例化传出
    }
    
    var box = { //字面量对象
        name: 'Lee',
        arr: ['哥哥', '妹妹', '姐姐']
    };
    
    var box1 = object (box); //传递
    alert(box1.name);

    box1.arr.push('父母');
        var box2 = obj(box); //传递
        alert(box2.name);

    但是ECMAscript5定义了Object.create()方法,可以直接使用,他有俩个参数,下面来一个例子:

    var person = {
        name: "Tom",
        age: 23,
        job: "web前端工程师"
    };
    
    var anotherPerson = Object.create(person, {
        name: {
            value: "Mike"
        }
    });
    alert(anotherPerson.name);

    在上面这个例子中,create的第二参数是一个对象,其中的属性如果和person重名,则会覆盖person的属性。

     5、借用构造函数实现继承

    function SuperType() {
        this.colors = ["red", "blue", "green"];
    }
    
    function SubType() {
        SuperType.call(this) //或者apply()
    }
    
    var instance1 = new SubType();
    instance1.colors.push("black");
    alert(instance1.colors);
    var instance2 = new SubType();
    alert(instance2.colors);

    借用构造函数也可以通过子对象向父对象传递参数

    function SuperType(name) {
        this.name = name
    }
    
    function SubType() {
        SuperType.call(this, "Tom") //或者apply()
    }
    var instance1 = new SubType();
    alert(instance1.name);

    八、JavaScript ES5 对象方法

    1、新的对象方法

    Object.defineProperty(object, property, descriptor)
    
    // 添加或更改多个对象属性
    Object.defineProperties(object, descriptors)
    
    // 访问属性
    Object.getOwnPropertyDescriptor(object, property)
    
    // 以数组返回所有属性
    Object.getOwnPropertyNames(object)
    
    // 以数组返回所有可枚举的属性
    Object.keys(object)
    
    // 访问原型
    Object.getPrototypeOf(object)
    
    // 阻止向对象添加属性
    Object.preventExtensions(object)
    
    // 如果可将属性添加到对象,则返回 true
    Object.isExtensible(object)
    
    // 防止更改对象属性(而不是值)
    Object.seal(object)
    
    // 如果对象被密封,则返回 true
    Object.isSealed(object)
    
    // 防止对对象进行任何更改
    Object.freeze(object)
    
    // 如果对象被冻结,则返回 true
    Object.isFrozen(object)

    1、添加或更改属性值

    Object.defineProperty(object, property, {value : value})

    更改属性值:

    var person = {
      firstName: "Bill",
      lastName : "Gates",
      language : "EN" 
    };
    
    // 更改属性
    Object.defineProperty(person, "language", {value : "ZH"});

    向对象添加新属性:

    // 创建对象
    var person = {
      firstName: "Bill",
      lastName : "Gates",
      language : "EN"
    };
    
    // 添加属性
    Object.defineProperty(person, "year", {value:"2008"});

    ES5 允许更改以下属性元数据:

    writable : true      // 属性值可修改
    enumerable : true    // 属性可枚举
    configurable : true  // 属性可重新配置
    writable : false     // 属性值不可修改
    enumerable : false   // 属性不可枚举
    configurable : false // 属性不可重新配置

    ES5 允许更改 getter 和 setter:

    // 定义 getter
    get: function() { return language }
    // 定义 setter
    set: function(value) { language = value }

    此例使语言为只读:

    Object.defineProperty(person, "language", {writable:false});

    此例使语言不可枚举:

    Object.defineProperty(person, "language", {enumerable:false});

    添加 Getter 和 Setter

    Object.defineProperty() 方法也可以用于添加 Getter 和 Setter:

    // 创建对象
    var person = {firstName:"Bill", lastName:"Gates"};
    
    // 定义 getter
    Object.defineProperty(person, "fullName", {
      get : function () {return this.firstName + " " + this.lastName;}
    });

    2、列出所有属性

    此例列出对象的所有属性:

    var person = {
      firstName: "Bill",
      lastName : "Gates"
      language : "EN" 
    };
    
    Object.defineProperty(person, "language", {enumerable:false});
    Object.getOwnPropertyNames(person);  // 返回属性数组

    3、列出可枚举的属性

    此例只列出对象的所有可枚举属性:

    var person = {
      firstName: "Bill",
      lastName : "Gates"
      language : "EN" 
    };
    
    Object.defineProperty(person, "language", {enumerable:false});
    Object.keys(person);  // 返回可枚举属性的数组
  • 相关阅读:
    构建WCF的消息代理
    使用LINQPad调试Linq和Entity Framework
    Memcached快递上手之C#
    使用PDFBox提取PDF文件中文本
    Asp.net使用HttpHandler优化Css样式文件
    Asp.net使用JQuery实现放大图片效果
    在Asp.net应用程序中构建基于WCF Web.Api的服务
    MsTest中实现类似NUnit中Assert.Throws
    JVM栈帧之局部变量表
    Tomcat源码分析(六)日志记录器和国际化
  • 原文地址:https://www.cnblogs.com/springsnow/p/12304178.html
Copyright © 2011-2022 走看看