javascript对象(5)

x33g5p2x  于2021-08-23 转载在 JavaScript  
字(4.4k)|赞(0)|评价(0)|浏览(377)

六对象

对象有属性,有方法

数据属性

  • Configurable :是否可以重新定义属性
  • Enumerable :表示能否通过 for-in 循环返回属性
  • Writable :表示能否修改属性的值
  • Value :包含这个属性的数据值
		var person = {}
        Object.defineProperty(person,"name",{
            writable:false,
            value : "胡二升"
        })
        console.log(person.name)//  "胡二升"
       

定义多个属性

 		var person = {}
        Object.defineProperties(person,{name:{
            writable:false,
            value : "胡二升"
        }, age: {
            value: 24
        }})
        console.log(person.name)//  "胡二升"
        console.log(person.age)// 24

6.1 创建对象的几种方式

obejct对象

 	   var person = new Object();
	   person.name="zszxz";
       person.age = 18;
       person.callName =  function (){
            alert(window.color);
        }

对象字面量语法

var person = {
           name: "zszxz",
           age:18,
           callName: function(){
               alert(this.name)
           }
       }

工厂模式

        function getPerson(name,age){
           var person = {
           name: name,
           age: age,
           callName: function(){
               alert(this.name)
           }
           }
           return person;
        }
        var person = getPerson("胡二升",24)

构造函数模式

普通函数通过new就可以作为构造函数

function Person(name,age){
           this.name = name;
           this.age = age;
        }
        var person = new Person("胡二升",24)

obj的作用域中调用创建person,此时obj对象拥有了Person的属性

  		function Person(name,age){
           this.name = name;
           this.age = age;
        }
        var obj = new Object();
        Person.call(obj,"胡二升",24)
       alert(obj.age)

原型模式

prototype 属性指向 原型对象;通过该属性指定对象的属性或者方法;

        function Person(){
        }
        Person.prototype.name ="胡二升";
        Person.prototype.age = 24
        console.log(Person.prototype)

同时使用 hasOwnProperty() 方法和 in 操作符,就可以确定该属性到底是存在于对象中,还是存在于
原型中

function hasPrototypeProperty(object, name){
	return !object.hasOwnProperty(name) && (name in object);
}

属性都在对象中,使用in肯定返回都是true

        function Person(){
                }
        Person.prototype.name ="胡二升";
        Person.prototype.age = 24
        var person1 = new Person();
        console.log(person1.hasOwnProperty("name"))// false
        console.log("name" in person1)// true

使用 Object.keys() 方法 获取可遍历的key

		function Person(){
        }
        Person.prototype.name ="胡二升";
        Person.prototype.age = 24
        console.log(Object.keys(Person.prototype))// ["name","age"]

使用 Object.getOwnPropertyNames() 获取所有key

		function Person(){
        }
        Person.prototype.name ="胡二升";
        Person.prototype.age = 24
        //  ["constructor", "name", "age"]
        console.log(Object.getOwnPropertyNames(Person.prototype))

简化原型写法

 		function Person(){
        }
        Person.prototype = {
            name : "胡二升",
            age : 24
        }

原型模式缺点。省略了为构造函数传递初始化参数,所有实例在默认情况下都将取得相同的属性值

构造模式和原型模式

构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性

		function Person(name, age){
            this.name = name;
            this.age = age;
        }
        Person.prototype = {
            constructor: Person
        }
        var person = new Person("胡二升",24)
        console.log(person.name)//  "胡二升"
        console.log(person.age)// 24

动态原型模式

仅当,callName方法不存在使用原型添加对应的方法;

        function Person(name, age){
            this.name = name;
            this.age = age;
        }
        if(typeof callName != "function"){
            Person.prototype = {
                callName: function(){
                    console.log(this.name)
                }
            }
        }
        
        var person = new Person("胡二升",24)
        person.callName();

寄生构造模式

和构造模式有点类似,不同之处里面先创建一个对象,然后进行方法属性赋值;

        function Person(name, age){
            var obj = new Object();
            obj.name = name;
            obj.age = age;
            return obj;
        }
        
        var person = new Person("胡二升",24)
        console.log(person)// {name: "胡二升", age: 24}

稳妥构造模式

  • 创建对象不用this;
  • 不使用new 调用构造函数
 	function Person(name, age){
            var obj = new Object();
            obj.name = name;
            obj.age = age;
            return obj;
        }
        
        var person = Person("胡二升",24)
        console.log(person)// {name: "胡二升", age: 24}

6.2 继承

原型链

原型链的主要实现方法是让构造函数的 prototype 对象等于另一个类型的实例,实现层层递进的关系;

function Super(){

};


function Middle(){

};

function Sub(){

};
// 
Middle.prototype = new Super();
// 
Sub.prototype = new Middle();

var suber = new Sub();

所有函数的默认原型都是 Object 的实例,因此默认原型都会包含一个内部指针,指向 Object.Prototype 。这也正是所有的自定义类型都会继承 toString() 、valueOf() 等默认方法的根本原因

借用构造函数

在子类中,使用call 或者 apply 借调 超类的构造函数;

 		function Super(){
            this.name = "憨憨"
        };

        function Middle(){
            Super.call(this);
        };
        console.log(new Middle())//  {name: "憨憨"}

组合继承

有时候也叫做伪经典继承 将原型链和借用构造函数的技术组合的一种继承模式

       function Super(){
            this.name = "憨憨"
        };

        Super.prototype.callName = function() {
            console.log(this.name)
        }

        function Middle(){
            // 继承属性
            Super.call(this);
        };
        console.log(new Middle())//  {name: "憨憨"}
        //继承方法
        Middle.prototype = new Super();
        new Middle().callName()// "憨憨"

原型式继承

传入一个对象,返回一个原型对象为该对象的新对象

function object(o){
    function F(){};
    F.prototype = o;
    return new F();
}

寄生式继承

创建一个仅用于封装继承过程的函数,该函数在内部以某种方式增强对象,最后返回这个对象

function createAnother(original){
    //通过调用函数创建一个新对象
    var clone = object(original); 
    // 某种方式增强这个对象
    clone.sayHi = function(){  
        console.log("hi");
    }
    return clone;  // 返回这个对象
}

var person = {
    name: "憨憨"
}

var anotherPerson = createAnother(person);
anotherPerson.sayHi(); // "hi"

寄生式组合继承

通过借用构造函数来继承属性,通过原型链的混成形式来继承方法

function inheritPrototype(subType, superType){
    var prototype = object(superType.prototype); //创建对象
    prototype.constructor = subType; //增强对象
    subType.prototype = prototype; //指定对象
}

相关文章