对象

对象:多个数据的封装体,保存多个数据的容器(可以统一管理多个数据)

  • 分类:
    • 内建对象:由ES标准定义的对象,在任何ES的实现都可以使用,例如:Math String Number Function Object

    • 宿主对象:由JS运行环境提供的对象,例如DOM BOM

    • 自定义对象:用户自己定义的

  • 组成:
    • 属性:由属性名(字符串)和属性值(任意类型)构成
    • 方法:一种特殊的属性(属性值是函数)
  • 访问属性
    • 对象.属性名:属性名必须是合法的标识符(字母、数字、下划线、$)
    • 对象["属性名"]:任何情况下都能使用
    • 对象[变量名]:在[]传入一个变量,会读取变量的值代表的属性,操作更加灵活
let obj={
	name:'jack'
}
// 属性名必须是合法的标识符(字母、数字、下划线、$)
console.log(obj.name)//'jack'
// 属性名可以是任何字符串
console.log(obj['name'])//'jack'
// 读取的是name变量的值代表的属性,因为变量name=undefined,所以obj.undefined=undefined
console.log(obj[name])//'undefined'
---------------------------------------------------
let flower='rose'
let obj2={
	rose:'red'
}
console.log(obj2.rose)//red
console.log(obj2['rose'])//red
console.log(obj2[flower])//red

创建对象

  • 1、new操作符:先创建空对象,再动态添加属性。用于最初对象的内部属性不确定时
    缺点:语句太多
    let obj=new Object()
        obj.name='tim'
        obj.age=19
  • 2、对象字面量:适用于创建时对象内部属性是确定的。
    let obj={
            name:'jack',
            age:19,
            sayHello:function () {
                console.log('hello');
            }
        }
    缺点:创建多个对象时,大量代码重复
  • 3、使用工厂方法:通过工厂函数动态创建对象,并将对象返回。适用于创建多个对象
    function createPerson(name,age) {
            let obj={}
            obj.name=name
            obj.age=age

            return obj
        }
        function createDog(name,age) {
            let obj={}
            obj.name=name
            obj.age=age

            return obj
        }
        let person=createPerson('tim',19)
        let dog=createDog('bigYellow',3)
        console.log(typeof person);//object
        console.log(typeof dog);//object
        console.log(person instanceof createPerson);//false
        console.log(dog instanceof createDog);//false
      缺点:对象没有具体的类型,返回都是object,无法判断对象是谁的实例
  • 4、构造函数的方式,与工厂函数方式的区别:没有显示的创建对象;没有返回语句;构造函数名需要一般大写,其他一般小写;知道是谁的实例(通过 instanceof 可以看出其既是Object的实例,又是Person的实例)
    function CreatePerson(name,age) {
            this.name = name
            this.age = age
            this.sayHello = function () {
                console.log('hello');
            }
        }
            let person1 = new CreatePerson('tim', 19)
            let person2 = new CreatePerson('jack', 29)
            console.log(typeof person1);//object
            console.log(person1 instanceof CreatePerson);//true

            console.log(person2.sayHello === person1.sayHello)//false
        缺点:person1,person2有一个相同的sayHello方法,但是它们并不是同一个函数的实例,创建两个完成同样任务的Function实例的确没有必要;况且有this对象在,根本不用在执行代码前就把函数绑定到特定对象上面。
          
        function CreatePerson(name,age) {
            this.name = name
            this.age = age
            this.sayHello = fun
        }
        function fun () {
            console.log('hello');
        }
            let person1 = new CreatePerson('tim', 19)
            let person2 = new CreatePerson('jack', 29)
            console.log(typeof person1);//object
            console.log(person1 instanceof CreatePerson);//true

            console.log(person2.sayHello === person1.sayHello)//true
    缺点:利用函数定义转移到构造函数外部来解决上面的问题,但是当对象有多个方法时就需要在定义多个全局函数,大量占用命名空间并且不安全
    总结:如果将方法函数写在构造函数中,那么在每次创建对象时都会实例化一个方法(方法是函数,函数也是对象),所以每个对象的方法都
不一样。将方法函数写在外面又会污染全局命名空间,并且不够隐私。这就出现了原型方式创建对象
  • 5、构造函数+原型
    function Person(name,age) {
            this.name=name
            this.age=age
        }
        Person.prototype.sayHello=function () {
            console.log('hello');
        }
        let p=new Person('jack',19)
        p.sayHello()
posted @ 2019-11-22 17:22  我就是要学习  阅读(165)  评论(0编辑  收藏  举报