创建对象

(1) 工厂模式

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 person1 = createPerson("Nicholas", 29, "Software Engineer");
var person2 = createPerson("Greg", 27, "Doctor");
存在的问题:没有解决对象时别问题(怎么知道一个对象的类型)

  (2)构造函数模式

注意点:构造函数始终都应该以一个大写字母开头,而非构造函数则应该以一个小写字母开头

function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
};
}
与上面进行比较
1/没有显示的创建对象
2/直接将属性和方法赋给了this对象
3/没有return语句
var person1 = new Person("Nicholas", 29, "Software Engineer"); 
var person2 = new Person("Greg", 27, "Doctor");
创建Person新实例必须使用new操作符,对应着四个步骤
1/创建新的对象
2/将构造函数的作用域给新对象
3/执行构造函数中的代码
4/返回新对象 //作为普通函数调用
Person(Greg,27,Doctor)//添加到window
window.sayName();
//在另一个对象的作用域中调用
var o=new Object();
Person.call(o,Kristen,25,Nurser)
o.sayName() 存在的问题:每个方法都要在每个实例上重新创建一遍,person1和person2都有一个sayName()方法,但实际这两个方法不知一样的

  (3)原型模式

每个函数都有一个prototype属性,这个属性是一个指针,指向一个对象
好处:可以让所有对象实例共享它所包含的属性和方法
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
person1.sayName(); //"Nicholas"
var person2 = new Person();
person2.sayName(); //"Nicholas"
alert(person1.sayName == person2.sayName); //true //说明:在ECMAScript新增方法Object.getPrototypeOf()

alert(Object.getPrototypeOf(person1) == Person.prototype); //true
   alert(Object.getPrototypeOf(person1).name); //"Nicholas"

在这里,解析器实际执行了两次搜索,第一次:person1有name属性吗,答:没有 ;第二次:person1的原型有这个属性吗,答:有。

//若实例存在和实例原型中一样的属性同名,那么实例中的属性会屏蔽原型中的属性

function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
var person2 = new Person();
person1.name = "Greg";
alert(person1.name); //"Greg"——来自实例
alert(person2.name); //"Nicholas"——来自原型
delete person1.name;
alert(person1.name); //"Nicholas" ——来自原型

//原型与in操作符

in操作符会在通过对象访问给定属性时返回true,无论该属性存在于实例还是原型中

alert(person1.hasOwnProperty("name")); //false

alert(person1.hasPrototypeProperty("name")) // true

alert("name" in person1); //true

person1.name = "Greg";
alert(person1.name); //"Greg" ——来自实例
alert(person1.hasOwnProperty("name")); //true

//hasOwnProperty判断是来自于原型属性时 返回false;

//hasPrototypeProperty判断是来自于原型属性时,返回true;

最新文章

  1. gbdt推导和代码
  2. BZOJ4517: [Sdoi2016]排列计数
  3. mfc中Button、Edit Control和MFC EditBrowse Control的用法
  4. Training little cats_矩阵快速幂
  5. linux进程管理之服务
  6. $http.post发的数据,后台取不到两种解决方案
  7. linux 线程备忘
  8. 在Windows环境下使用MinGW编译Qt 4.8.6
  9. ASP.NET MVC项目
  10. vue2.0 实现导航守卫(路由守卫)
  11. Android Studio报错:the selected directory is not a valid home for unknow sdk
  12. xml解析多个结点方法(C#)
  13. 【转】javascript 浮点数运算问题
  14. PAT1046: Shortest Distance
  15. 详解docker实战之搭建私有镜像仓库 - kurbernetes
  16. js判断iPhone XS、iPhone XS Max、iPhone XR
  17. mac环境下mongodb的安装和使用
  18. ThreadLocal(一):Thread 、ThreadLocal、ThreadLocalMap
  19. How to ignore files and directories in subversion?
  20. js 日期,时间函数 及相关运算大全

热门文章

  1. WangEditor+thinkphp5【真实可用+原创】
  2. Mysql5.8解压版安装问题:TCP/IP, --shared-memory, or --named-pipe should be configured on NT OS
  3. oracle学习笔记第三天
  4. 2017年年度总结 & 2018年计划
  5. RoR - Restful Actions
  6. zblog如何更改数据库配置以及生效
  7. ThinkPHP 5 验证码
  8. python continue的应用
  9. JMeter-性能测试监控(解决.sh文件的启动)
  10. EF中,保存实体报错:Validation failed for one or more entities. 如何知道具体错误在哪?