对象

254 阅读4分钟

1.理解对象

每个对象都是基于一个引用类型创建的,引用类型可以是原生类型,也可以是自定义类型。

2.属性类型

ECMAScript中有两种属性: 数据属性和访问器属性。

2.1数据属性:

包含一个数据值的位置,在这个位置可以读写数据,它有4个描述其行为的特性。 直接定义在对象上的属性,他们以下3个特性都被设置为true,value设置为指定的值。

configurable:true; //表示属性可配置,能通过delete()删除属性
enumerable:true;//表示属性可枚举 for in
writable:true;//表示属性可修改
value:undefined//属性值存在的位置,默认undefined

2.2访问器属性:

configurable:true; //表示属性可配置,能通过delete()删除属性
enumerable:true;//表示属性可枚举 for in
get:读取属性时调用的函数
set:写入属性时调用的函数

使用Object.defineProperty()方法可以修改默认特性或添加一个或多个新属性

定义多个属性:

var book = { };
Object.defineProperties(book,{
	-year:{
        writable:true;
        value:3004
	},
	edition{
        writable:true;
        value:1
	},
	year:{
        get:function(){
			return this.-year;
		},
		set:function(newvalue){
             if(newvalue>2004){
			this.-year = newvalue;
		}
        }	
	}
})

2.3 对象属性的枚举

所有开发人员定义的属性都是可以枚举的,包括原型上的属性,但是设置Enumerable:false的属性除外。

方法一

Object.keys(obj) //可枚举所有的实例属性

Object.keys(obj.__prototo__)//枚举原型上的属性

方法二

for in//枚举所有可枚举的属性,包括继承自原型的属性。

方法三

Object.getOwnPropertyNames()//枚举所有实例属性,包括设置Enumerable:false的属性。

参考文章:blog.csdn.net/baidu_31333…

2.4对象属性值的枚举

for...of 为ES6新增的方法,主要来遍历可迭代的对象(包括 Array , Map , Set , arguments 等),它主要用来获取对象的属性值,而 for...in 主要获取对象的属性名。

3.对象、构造函数及原型

3.1创建对象

构造函数可以通过new操作符来创建对象,也可以当普通函数使用,也可以利用call和apply在另一个对象的作用域中调用。

共享属性和方法:如果构造函数的属性和方法写在原型prototype上,那么通过new创建出的对象,其属性和方法就是共享原型的两个实例。在新对象上修改或添加属性都不会影响原型和其他新对象的属性。

私有属性:如果直接写在构造函数中,那么new出的对象是两个相互独立的实例。

面向对象编程:一般情况下,将属性直接写在构造函数中,可以自定义配置新对象的属性,将方法写在构造函数的原型上,所有的新对象共享同一个原型上的方法。

组合使用构造函数和原型模式
function Person(name,age,sex){
    this.name = name;
    this.age = age;
    this.sex = sex;
}
Person.prototype = {
    set:function(){
        console.log(this.name)
    }
}
var person1 = new Person('gebilaowang',38,'male');
person1.set();

3.2原型和构造函数的关系:

原型

3.3检测方法

检测一个属性来自实例还是原型:

person1.hasownProperty()//true表示来自实例  false表示来自原型 

3.4原生对象的原型

通过原生对象的原型,不仅可有取得所有默认的方法,而且可以定义新方法。

例如:Array.prototype.sum = function(){}

4 继承

4.1圣杯模式:

        function Father() {
            this.age = 18;
        }
        Father.prototype.lastName = 'Jack';
        Father.prototype.fly = function(){
            console.log('gogogo')
        }
        
        function Son() {}
        Son.prototype.sex = 'male';
        Son.prototype.dan = function(){
            console.log('biubiubiu')
        }
     
        function inherit(Target, Origin) {
            function F() {};
            F.prototype = Origin.prototype;
            Target.prototype = new F();
        }

        inherit(Son, Father);
        var son = new Son();
        var father = new Father();

       
        测试:
        console.log(son.lastName); //Jack
        console.log(son.sex); //male
        console.log(father.sex); //undefined
        console.log(son.age)//undefined
        console.log(father.age)//18
        son.dan()//biubiubiu
        father.dan() //Uncaught TypeError: father.dan is not a function
        father.fly()//gogogo
        son.fly()//gogogo

结果:

  • 可以继承父级原型上的属性和方法,父级私有属性不能继承。
  • 子级的属性和方法不会影响到父级。

4.2 ES 5另一种方法

Son.prototype.__proto__ = Father.prototype;

4.3 ES 6 方法一

Object.setPrototypeOf(Son,Father);(需要降级浏览器才支持)

4.4 ES 6 方法二

(需要降级浏览器才支持)

Class plane{
    static alive(){
        return true;  //静态属性  属于构造函数,实例上没有该属性
    }
    construtor:(name){
        this.name = name//私有属性
    }   
    fly(){
        //原型方法
    }
}

Class AttackPlane extends Plane{
    constructor (name){
     super(name); //继承私有属性
	this.logo='duyi'
    }
}
var oAt = new AttackPlane();  //继承了plane的原型方法、私有属性及静态属性。