Javascript高级程序设计——面向对象之创建对象

对象创建方法:

  1. 工厂方法
  2. 构造函数模式
  3. 原型模式
  4. 组合构造函数和原型模式
  5. 寄生构造函数模式
  6. 问题构造函数模式

工厂模式:

function Person(name, age){
    var obj = new Object();        //创建对象

    obj.name = name;               //添加方法、属性
    obj.age = age;
    obj.sayName = function(){
        alert(this.name);
    }

    return obj;                    //返回对象
}var people = Person("yangxunwu", 24);

缺点:返回的对象全部是object的实例,无法完成对象识别

构造函数模式:

function Person(name, age){
    this.name = name;            //添加方法、属性
    this.age = age;
    this.sayName = function(){
        alert(this.name);
    };
}

var people = new Person("yangxunwu", 24);//注意多了new操作

 构造函数创建实例时,必须用new操作符,经历四个步骤:

  1. 创建对象
  2. 将构造函数的作用域赋给对象。(this指向新对象)
  3. 执行构造函数代码。
  4. 返回新对象。

 缺点:虽然创建的实例可以通过instanceof操作符 来识别,但函数无法复用。

原型模式:

function Person(){                      //创建空的构造函数
}

Person.prototype.age = age;                //构造函数原型上添加属性和方法,达到函数复用
Person.prototype.sayName = function(){
    alert(Person.prototype.name);
};

var people = new Person();

  当创建一个新函数时,会自动根据特定规则为函数创建prototype属性,这个属性是一个指针指向函数的原型对象,

原型对象会自动的获得一个constructor属性,这也是一个指针,指向拥有这个prototype属性的函数。

Pesson.prototype.constructor = Person

  创建自定义构造函数后,其原型对象自动获得constructor属性,其他的方法都从object继承。当通过构造函数创建

一个新实例后,实例自动获得一个指针,指向构造函数的原型对象,一般名称是__proto__属性。

  当代码读取某个属性时,一般会经过两个过程一个是在实例上搜索属性,搜索不到就通过__proto__属性到原型对象上搜索。

通过hasOwnProperty()方法,可以检测一个属性是存在实例中还是原型中,实例中返回true。

  原型对象上的属性可以让所有实例共享,但是当属性为引用类型时就会容易产生问题。

function Person(){
}

Person.prototype.names = ["yang", "zhang"];

var people1 = new Person();
var people2 = new Person();

people1.names   //["yang", "zhang"]
people2.names   //["yang", "zhang"]

people1.names.push("test");   //因为属性共享,而且是引用类型,所以names改变了

people1.names   //["yang", "zhang", "test"]
people1.names   //["yang", "zhang", "test"]

实例一般应该有自己的全部属性,这里没有

组合使用构造函数模式和原型模式

function Person(name, age){                //构造函数继承的属性是独有的
    this.name = name;
    this.age = age;
    this.friends = ["yang", "zhang"];
}

Person.prototype.sayName = function(){    //通过原型模式来共享方法
    alert(this.name);
}

//创建实例,实例不共享属性,共享方法
var people1 = new Person("yangxunwu", 24);
var people2 = new Person("hexiaoming", 6);

//访问引用类型
people1.friends;          //["yang", "zhang"]
people1.friends;          //["yang", "zhang"]

//为添加元素
people1.friends.push("wang");

people1.friends;          //["yang", "zhang","wang"] 元素被添加到people1的属性中,因为构造函数不共享属性
people1.friends;          //["yang", "zhang"]

people1.sayName === people2.sayName    //true。共享方法

动态原型模式:

function Person(name, age){                //动态原型模式
    this.name = name;
    this.age = age;
    this.friends = ["yang", "zhang"];

    if(Person.prototype.sayName != "function"){    //动态加载,只在第一次添加原型方法
        Person.prototype.sayName = function(){
        alert(this.name);
        }
    };
}

只在第一次调用构造函数时执行,之后原型已经完成初始化。

寄生构造函数模式:

function Person(name, age){
    var obj = new Object();                    //生成一个Objdetde对象

    obj.name = name;
    obj.age = age;
    obj.sayName = functon(){
        alert(this.name);
    }

    return obj;                                //返回的一直是Object的对象。
}

var people = new Person("yangxunwu", 24);    //与工厂模式的区别,坑
people.sayName();      //yangxunwu

返回的对象与构造函数或者构造函数的原型没关系,而且返回的一直是Object类型。只是把外部干的事放到内部干。

稳妥构造函数:

function Person(name, age){
    var obj = new Object();
    //定义私有变量和函数
    obj.doSomething = function(){
        alert(name);                   //定义可以访问私有变量和函数的方法,没有引用this
    }

    return obj;                        //返回对象,现在只有这个对象可以访问这些私有变量和函数。
}

var people = Person("yangxunwu", 24);  //没使用new
people.sayName();      //yangxunwu

稳妥构造就是没有公共的属性,不引用this,防止数据被其他应用程序破坏。稳妥构造函数与寄生构造函数不同:

  1. 新创建的对象方法不引用this
  2. 不使用new操作符来调用构造函数。
时间: 2024-10-05 08:59:34

Javascript高级程序设计——面向对象之创建对象的相关文章

Javascript高级程序设计——面向对象小结

ECMAScript支持面向对象编程,对象可以在代码执行时创建,具有动态扩展性而非严格意义上的实体. 创建对象方法: 工厂模式:简单的函数创建引用类型 构造函数模式:可以创建自定义引用类型,可以想创建内置对象一样使用new操作符,构造函数的函数无法得到复用,不能共享函数. 原型模式:利用构造函数的prototype属性来指定共享的属性和方法,组合使用构造函数和原型模式时,使用构造函数定义实例属性,原型模式来共享方法. javascript主要通过原型链实现继承,将一个类型的实例赋值给另一个原型对

Javascript高级程序设计——面向对象之实现继承

原型链: 构造函数中都有一个prototype属性指针,这个指针指向原型对象,而创建的实例也有指向这个原型对象的指针__proto__.当实例查找方法时先在实例上找,找不到再通过__proto__到原型对象上查找.如果原型对象是另一个类型的实例,那么原型对象包含一个指向另一个原型对象的指针.另一个原型对象中也包含指向另一个构造函数的指针. 原型连继承function superValue(){ this.superValue = "superValue"; } superValue.p

JavaScript高级程序设计: 面向对象编程

工厂模式 工厂模式虽然解决了创建多个相似对象的问题,但没有解决对象识别问题. 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('Alice',23,'PHP

《Javascript高级程序设计》:创建对象

工厂模式 1 function createPerson(name,age, job){ 2 var o = new Object(); 3 o.name = name; 4 o.age = age; 5 o.job = job; 6 o.sayName = function(){ 7 alert(this.name); 8 }; 9 return o; 10 } 11 var person1 = createPerson("Nicholas", 29, "Software

《JavaScript高级程序设计》学习笔记(5)——面向对象编程

欢迎关注本人的微信公众号"前端小填填",专注前端技术的基础和项目开发的学习. 本节内容对应<JavaScript高级程序设计>的第六章内容. 1.面向对象(Object-Oriented, OO)的语言有一个标志,那就是它们都有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象.前面提到过,ECMAScript中没有类的概念,因此它的对象也与基于类的语言中的对象有所不同. ECMA-262把对象定义为:"无序属性的集合,其属性可以包含基本值.对象或者函数.

JavaScript高级程序设计学习笔记--面向对象程序设计

工厂模式 虽然Object构造函数或对象字面量都可以用来创建单个对象,但这些方式有个明显的缺点:使用同一个接口创建很多对象,会产生大量的重复代码.为解决这个问题,人们开始使用 工厂模式的一种变体. function createPerson(name,age,job){ var o=new Object(); o.name=name; o.age=age; o.job=job; o.sayName=function(){ alert(this.name); }; return o; } var

创建对象(《JavaScript高级程序设计》思维导图)

面向对象(Object-Oriented, OO)的语言有一个标志,那就是它们都有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象.而 ECMAScript 中没有类的概念,所以我们可以使用对象模拟出类.ECMA-262 把对象定义为:“无序属性的集合,其属性可以包含基本值.对象或者函数.”严格来讲,这就相当于说对象是一组没有特定顺序的值.对象的每个属性或方法都有一个名字,而每个名字都映射到一个值. 以下是<JavaScript高级程序设计>中介绍的创建对象的方法,我把它们总结成思维

javascript高级程序设计——笔记

javascript高级程序设计--笔记 基本概念 基本数据类型包括Undefined/Null/Boolean/Number和String 无须指定函数的返回值,实际上,未指定返回值的函数返回的是一个特殊的undefined值 变量.作用域和内存问题 基本类型值在内存中占据固定大小的空间,因此保存在栈内存中 引用类型的值是对象,保存在堆内存中 确定一个值是哪种基本类型用typeof,确定一个值是哪种引用用instanceof 所有变量都存在于一个执行环境当中,这个执行环境决定了变量的生命周期,

JavaScript高级程序设计(读书笔记)(六)

本笔记汇总了作者认为"JavaScript高级程序设计"这本书的前七章知识重点,仅供参考. 第六章 面向对象的程序设计 面向对象(Object-Oriented, OO)的语言有一个标志,那就是它们都有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象.但ECMAScript中没有类的概念,因此它的对象也与基于类的语言中的对象有所不同.ECMAScript把对象定义为:"无序属性的集合,其属性可以包含基本值.对象或者函数."严格来讲,这就相当于说对象是一组没