bob体育官方平台
【bob体育官方平台】JavaScript检测实例属性, 原型属性_javascript技巧_脚本之家

JavaScript对象的属性分为两种存在形态. 一种是存在实例中, 另一是存在原型对象中.

1.创建对象 复制代码 代码如下: var person = new Object(); person.name = "RuiLiang"; person.age = 30; person.job = "Teacher"; person.sayName = function ; }; person.sayName(); 2.工厂模式 缺点:不能识别对象 复制代码 代码如下: function createPerson { var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function ; }; return o; } var person1 = createPerson; var person2 = createPerson; person1.sayName(); //"阿亮" person2.sayName(); //“俊俊” 3.构造函数模式 缺点:缺少封装性 复制代码 代码如下: function Person { this.name = name; this.age = age; this.job = job; this.sayName = sayName; } function sayName; } var person1 = new Person; var person2 = new Person; person1.sayName; 4.原型模式 缺点:所有属性被实例共享 复制代码 代码如下: function Person() { } Person.prototype.name = "ALiang"; Person.prototype.age = 30; Person.prototype.job = "Teacher"; Person.sayName = function ; } hasOwnProperty()方法检测某一属性是不是实例属性,如果是返回 true person1.hasOwnProperty; //name是不是person1的属性 in 操作符:通过对象访问的属性是否存在,若存在返回 true,不管属性存在实例中还是原型中 alert; //name属性若存在返回 true 确定属性在原型中还是对象中的方法: 复制代码 代码如下: function hasPrototypeProperty { return !object.hasOwnProperty && ; } //用法 var person = new Person(); alert(hasPrototypeProperty; //true person.name = "Grey"; //改变原型中name的值 alert(hasPrototypeProperty; //false isPrototypeOf()方法是用来判断指定对象object1是否存在于另一个对象object2的原型链中,是则返回true,否则返回false。 格式如下: object1.isPrototypeOf; object1是一个对象的实例; object2是另一个将要检查其原型链的对象。 原型链可以用来在同一个对象类型的不同实例之间共享功能。 如果 object2 的原型链中包含object1,那么 isPrototypeOf 方法返回 true。 如果 object2 不是一个对象或者 object1 没有出现在 object2 中的原型链中,isPrototypeOf 方法将返回 false。 复制代码 代码如下: //字面量重写原型对象 function Person(){ } Person.prototype = { constructor : Person, name : "ALiang", age : 30, job : "Teacher", sayName : function; } }; 5.构造函数和原型混合模式 具有构造函数模式和原型模式的优点,属性用构造函数模式,方法用原型模式 //这种模式使用最广泛 复制代码 代码如下: function Person { this.name = name; this.age = age; this.job = job; this.friends = ["xuyun","wuxueming"]; } Person.prototype = { constructor : Person, sayName : function; } }; var person1 = new Person("ALiang",30,"Teacher"); var person2 = new Person; person1.friends.push; alert; //"xuyun","wuxueming","JunJun" alert; //"xuyun","wuxueming" 6.动态原型模式 复制代码 代码如下: function Person { this.name = name; this.age = age; this.job = job; if (typeof this.sayName != "function"){ //这里的sayName可以是任何初始化后存在的方法或属性 Person.prototype.sayName = function() { //不能用字面量形式 alert; }; } 7.寄生构造函数模式 8.稳妥构造函数模式

bob体育app,Object类型是JavaScript中使用最多的一种类型。创建Object实例的方式有多种,接下来一一列举。

根据上述, 检测属性的时候会出现4种情况

1. Object构造函数

bob体育官方平台,var person = new Object();
person.name = "Brittany";
person.age = 23;
person.job = "web front-end engineer";
person.sayName = function() {
    console.log(this.name);
};
person.sayName();   //Brittany

既不存在实例中, 也不存在原型对象中存在实例中, 不存在原型对象中不存在实例中, 存在原型对象中既存在实例中, 也存在原型对象中

2. 对象字面量模式

var person = {
    name: "Brittany",
    age: 23,
    job: "web front-end engineer",
    sayName: function() {
        console.log(this.name);
    }
};
person.sayName();

虽然Object构造函数或对象字面量都可以用来创建单个对象,但这些方式有个明显的缺点:使用同一个接口创建很多对象,会产生大量的重复代码。为解决这个问题,可以使用工厂模式的一种变体。

1.hasOwnPrototype()

3. 工厂模式 

function createPerson(name, age, job) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function() {
        console.log(this.name);
    };
    return o;
}

var person1 = createPerson("Brittany", 23, "Software Engineer");
var person2 = createPerson("Sam", 26, "Software Engineer");
console.log(typeof person1);   //Object

工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题(即怎样知道一个对象的类型)。如代码中只能检测出person1为Object类型。随着JavaScript的发展,又一个新模式出现了。

hasOwnPrototype()接受一个字符串格式的属性名称, 如果实例本身存在该属性, 返回true. 否则, 返回false.

4. 构造函数模式

function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function() {
        console.log(this.name);
    }    
}
var person1 = new Person("Brittany", 23, "Web front-end engineer");
var person2 = new Person("Closure", 26, "Manager");
person1.sayName();
person2.sayName();
console.log(person1.sayName == person2.sayName);   //false

使用构造函数的主要问题:每个方法都要在每个实例上重新创建一遍。如代码中所示,person1的sayName和person2的sayName不相等。可以将函数定义转移到构造函数外部来解决。

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

sayName函数的定义转移到了构造函数外部。而在构造函数内部,我们将sayName属性设置成等于全局的sayName函数。这样一来,由于sayName包含的是一个指向函数的指针,因此person1和person2对象就共享了在全局作用域中定义的同一个sayName()函数。这的确解决了两个函数做同一件事的问题,可是新问题又来了:在全局作用域中定义的函数实际上只能被某个对象调用,这让全局作用域有点名不副实。而更让让人无法接受的是:如果需要定义很多方法,那就要定义很多个全局函数,于是这个自定义的引用类型就无封装性可言。这些问题可通过使用原型模式来解决。

返回顶部