对象的基本方法

一、对象的特点

对象,就是类。类,就是具有相同的属性和方法。但是,js里面没有类的概念。

 

二、js创建对象的方法

js创建对象常用的有4种方法,Object构造函数、对象字面量和工厂函数、自定义构造函数模式。

前两个一次只能创造一个对象,后两个可以大批量创造对象。

工厂函数:没有办法检验你创建的对象类型。

自定义构造函数模式:可创建特定类型的对象。

1、Object构造函数

//1-Object构造函数
var person1=new Object();
person1.name='Alice';
person1.age=18;
person1.sayName=function(){
    console.log(this.name);
}
person1.sayName(); //Alice

 构造函数可以用来创建特定类型的对象。也可以创建自定义的构造函数,从而定义自定义对象类型的属性和方法。按照惯例,构造函数始终是以一个大写字母开始,非构造函数以小写字母开头。

构造函数模式创建的对象会有一个constructor(构造函数)属性,该属性指向构造函数。

function Person(name,age,job){
    this.name=name;
    this.job=job;
    this.age=age;
}
var p1= new Person("Jin",24,'singer');
var p2 = new Person("NamJoon",23,'artist');
console.log(p1.constructor==Person)  //true

 instanceof操作符既可以判断Object类型,又可以判断Person类型。

console.log(p1 instanceof Object)  //true
console.log(p2 instanceof Person)  //true

2、对象字面量

//2-对象字面量,注意隔开用的是逗号,表示用的是冒号
var person2={
    name:'Tony',
    age:19,
    sayName:function(){
        console.log(this.name);
    }
}
person2.sayName();//Tony

3、工厂函数,不是用new操作符,没有办法检查他是什么类型的,只能检查到他是Object

function person3(name,age,sayName){
    var obj=new Object();
    obj.name=name;
    obj.age=age;
    obj.sayName=function (){
        console.log(this.name);
    }
    return obj;
}
var person3_1=person3('NamJoon',24);
person3_1.sayName();//NamJoon
console.log(person3_1 instanceof Object);//true

4、自定义构造函数,可以检查到他的函数名称,这也是他比工厂函数高级的地方

//4-构造函数模式,注意,一定要大写,与其他方法区分开。方法一般是小写
function Person4(name,age,sayName){
    this.name=name;
    this.age=age;
    this.sayName=function(){
        console.log(this.name);
    }
}
var person4_1=new Person4('Jin',25);
var person4_2=new Person4('suga',27);
person4_2.sayName();//suga
var cons=person4_1.constructor===person4_2.constructor;//注意这个属性,他们都指向Person4。
console.log(cons);//true
console.log(person4_1.constructor);//Person4
//注意,这两个person的类型既是Person4,也是Object
console.log(person4_1 instanceof Object);//true

扩展问题:当你使用new的时候,到底经历了什么?

(1)创建一个新对象

(2)将构造函数的作用域赋给新对象,因此,this指向这个新对象

(3)执行构造函数中的代码

(4)返回新对象

//在某个对象的作用域内调用构造函数
var obj=new Object();
Person4.call(obj,'BTS',100);
obj.sayName();//BTS

三、构造函数模式本身存在的缺陷——原型模式出现,拯救无法封装的缺陷

在上面,Person4创建的对象中,有个sayName的属性,该属性是个方法。为了简便,把这个方法拿到全局里,让sayName这个属性存储的只是一个指针,指向全局里的sayName方法。

function Person4(name,age,sayName){
    this.name=name;
    this.age=age;
    this.sayName=sayName();
    }

function sayName(){
    console.log(this.name);
}

如果这个对象有很多方法的话,那不就是要在全局里面写很多方法了吗?谁都能调用这些全局方法,那么这个所谓的自定义函数,就违背了封装性的概念了。所以,原型模式出现了。

function Person(){
}
Person.prototype.name='Alice';
Person.prototype.age=18;
Person.prototype.sayName=function(){
    console.log(this.name);
}
var person1=new Person();
person1.sayName();//Alice
var person2=new Person();
person2.name='王花花';
person2.sayName();//王花花

在上面这段代码中,构造函数变成了空函数,但是照样可以用它来生产对象。这是因为,

任何函数,都会有一个prototype属性。这个属性,指向函数的原型对象。在js中,函数与对象的关系,可以理解为相等,函数就是对象,对象就是函数。

原型对象是天然美女,没有加工过的。通过实例化后,不动他的属性,他就不变。而实例化后,如果又改变了他的属性,就有点像整容了,他的属性就变成了他整容之后的样子。也就是下面的那个‘王花花’。

四、获取对象里的属性和方法

两个:for in 和Object.keys(对象名)

for in返回的是能够通过对象访问的、可枚举的属性

function Person4(name,age,sayName){
    this.name=name;
    this.age=age;
    this.sayName=sayName;
    }
function sayName(){
    console.log(this.name);
}

for (var item in Person4){
    console.log(item);//Array(3) ["name", "age", "sayName"]
}
var keys=Object.keys(Person4);
console.log(keys);//Array[0],这是为什么呢?就因为没有给他添加值吗?

var p1=new Person4();
p1.name='alice';
p1.age=19;
var p1Keys=Object.keys(p1);
console.log(p1Keys);//Array(3) ["name", "age", "sayName"]
for(var item in p1){
    console.log('item-->'+item);//name,age,sayName
    console.log(typeof item);//3个string,不是数组
}

 -

要取得对象上所有可枚举的实例属性,可以使用ES5的Object.keys()方法。该方法会接受一个对象作为参数,返回一个字符串数组。

var person={
    name:"NamJoon",
    age:"24"
}
var keys = Object.keys(person);
console.log("keys-->>",keys) //Array(2) ["name","age"]

补充:单独使用in操作符时,如果属性存在,会返回true。

function Person(){    
}
var p1=new Person();
p1.name="Alice";
console.log("name" in p1) //true
原文地址:https://www.cnblogs.com/qingshanyici/p/10494940.html