js对象

创建js对象有三种方式:对象字面量、内置的构造函数、自定义的构造函数
对象既有属性、又有方法
1.对象字面量创建对象:

var dog = {
    name: "kitty",
    getName: function() {
        return "maomao";
    }
}

完全删除对象属性/方法:

delete dog.name;
delete dog.getName;

2.内置构造函数创建对象:

var dog = new Object();
dog.name = "kitty";
dog.getName = function() {
    return "maomao";
}

建议使用对象字面量的方式创建对象。
因为对象字面量:仅需要输入更短的字符;它强调了该对象仅是一个可变哈希映射,而不是从对象中提取的属性或方法;它并没有作用域解析;
而object构造函数:可能会继承其他人编写的遗留代码;Object构造函数仅接收一个参数,根据所传递的值的类型,Object可能会委派另一个内置构造函数来创建对象,并且返回了一个并非期望的不同对象
这里写图片描述
有作用域解析,可能以同样的名字创建了一个局部构造函数,解析器需要从调用Object()的位置开始一直向上查询到作用域链,直到发现全局object构造函数;

3.自定义构造函数创建对象:

var Person = function (name) {
    this.name = name;
    this.say = function () {
        return "I am " + this.name;
    }
}

var lily = new Person ("lily");
lily.say(); // 输出结果为I am lily

当以new操作符调用构造函数时,函数内部将会发生以下情况:
(1) 创建一个空对象并且this变量引用了该对象,同时还继承了该函数的原型;
(2) 属性和方法被加入到this引用的对象中;
(3) 新创建的对象由this所引用,并且最后隐式地返回this(如果没有显式地返回其他对象)

var Person = function (name) {
    // 使用对象字面量模式创建一个新对象
    // var this = {};  // 此语句不是真相的全部,因为空对象实际上并不空,它已经从Person的原型中创建了许多成员,因此,更像是下面的语句:var this = Object.create(Person.prototype);

    // 向this添加属性和方法
    this.name = name;
    this.say = function () {
        return "I am " + this.name;
    } 
    // 隐式的返回this(如果没有显式地返回其他对象)
    // return this;
}

本例中将say()方法添加到this中,其造成的结果是在任何时候调用new Person()时都会在内存中创建一个新的函数,此种方式效率低下,因为多个实例之间的say()方法实际上并没有改变。
更好的选择是:将方法添加到Person类的原型中

Person.prototype.say = function () {
    return "I am " + this.name;
}

切记:可重用的成员,比如,可重用的方法,都应该放置到对象的原型中。

构造函数仍然只是函数,只不过它却以new的方式调用。如果在调用构造函数时忘记指定new操作符,会导致构造函数中的this**指向了全局对象(在浏览器中,this将会指向window)(注意:只有this这种模式才指向全局**):

var w = function() {
    this.g = "gg";
}
var w1 = w();
console.log(typeof w1); // 输出 undefined
console.log(w1.g); // 输出 undefined
console.log(window.g) // 输出 gg

所以,在使用构造函数时,要强制使用new的模式

对于简单的对象,不需要类似that这样的局部变量,可以仅仅从字面量中返回一个对象,如:

function Waffle() {
    return {
        tastes: "yummy"
    }
}
var first = new Waffle(),
    second = Waffle();
console.log(first.tastes);  // 输出 yummy
console.log(second.tastes); // 输出 yummy

但这种模式的问题它会丢失到原型的链接,因此任何您添加到Waffle()原型的成员,对于对象来说都是不可用的

为了解决前面模式的缺点,并使得原型属性可在实例对象中使用,那么,可以使用如下两种方法(思想:可以在构造函数中检查this是否为构造函数的一个实例,如果不是,构造函数可以再次调用自身,并且在这次调用中正确的使用new操作符)
方法一:

function Waffle() {
    if (!(this instanceof Waffle)) {
        return new Waffle();
    }
    this.tastes = "yummy";
}
Waffle.prototype.wantAnother = true;

方法二:

function Waffle() {
    if (!(this instanceof arguments.callee)) {
        return new arguments.callee();
    }
    this.tastes = "yummy";
} 
Waffle.prototype.wantAnother = true;

使用arguments.callee模式是基于这样的一个事实:即在每个函数内部,当该函数被调用时,将会创建一个名为arguments的对象,其中包含了传递给该函数的所有参数。同时,arguments对象中有一个名为callee的属性,该属性会指向被调用的函数。(注意:在ES5的严格模式中不支持arguments.callee属性)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值