<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> </head> <body> </body> <script> //一:创建单个对象的两种方式 //1:通过new 操作符 加上Object 构造函数去创建 var person = new Object(); person.name = "zhangsan"; person.age = 18; person.job = "frontend"; person.sayName = function () { alert(this.name); }; console.log(person); // 如果创建的对象包含大量的属性,代码会很多, // 为了简化创建大量属性的过程,因此出现了对象定义的简写形式,对象字面量。 //2:通过对象字面量,花括号,键值对的方式去创建。 var person2 = { name: "lisi", age: 20, job: "frontend", sayname: function () { alert(this.name); } }; console.log(person2); // 以上两种方法是用来创建单个对象,但是如果创建多个相似的对象时,会产生大量重复的代码因此产生了工厂函数 // 二:创建多个相似的对象的两种方式 //1:工厂模式 function ceratPerson(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 = ceratPerson("zhangsan", 18, "frontend"); var person2 = ceratPerson("lisi", 20, "frontend"); console.log(person1); console.log(person1.constructor);//function Object() { [native code] } //但是没有解决对象的标识性问题,就是无法判断创建出来的对象是什么类型的,因此出现了构造函数 //2:构造函数,创建特定类型的对象 function Person(name, age, job) { this.name = name; this. age = age; this.job = job; this.sayName = function () { alert(this.name); } } var person1 = new Person("zhangsan", 18, "frontend"); var person2 = new Person("lisi", 20, "frontend"); console.log(person1); console.log(person1.constructor); /* function Person(name,age,job){ this.name = name; this,age = age; this.job = job; this.sayName = function () { alert(this.name); } }*/ // 相对于工厂函数来说,解决了对象的标识性问题,同时代码也更加简洁。 //把构造函数当做函数 function Person(name, age, job) { this.name = name; this, age = age; this.job = job; this.sayName = function () { alert(this.name); } } //当做构造函数使用 var person1 = new Person("zhangsan", 18, "frontend"); person1.sayName();//zhangsan //当做普通函数使用 Person("lisi", 20, "frontend"); // 添加到window window.sayName();//lisi // 在另一个对象的作用域中调用 var o = new Object(); Person.call(o, "wangwu", 25, "frontend"); o.sayName(); //构造函数存在的问题 //方法无法复用,每个person实例都包含一个不同的function实例 function Person(name, age, job) { this.name = name; this. age = age; this.job = job; this.sayName = function () { alert(this.name); } } var person1 = new Person("zhangsan", 18, "frontend"); var person2 = new Person("lisi", 20, "frontend"); alert(person1.sayName == person2.sayName);//false //解决办法: //sayName 属性设置成全局的sayName函数 //该方法的缺点: // 1>全局函数只能被该构造函数创建的一类对象调用,名不符合 // 2>如果方法很多,就会定义很多全局函数,代码冗余,自定义的引用类型就没有任何封装性可言 function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.sayName = sayName; } function sayName() { alert(this.name); } var person1 = new Person("zhangsan", 18, "frontend"); var person2 = new Person("lisi", 20, "frontend"); alert(person1.sayName == person2.sayName);//true //3: 原型模式,实现方法的共享 function Person() { } Person.prototype.name = 'tom'; Person.prototype.age = 16; Person.prototype.friend = ['zhangsan', 'lisi']; Person.prototype.job = 'frontend'; Person.prototype.sayName = function () { alert(this.name); }; var person1 = new Person(); var person2 = new Person(); person1.sayName();//tom person2.sayName();//tom alert(person1.sayName == person2.sayName); //如果想改写属性,可直接在实例上添加属性值; person1.name = 'jerry'; person1.sayName(); // jerry person2.sayName(); // tom // 但是如果该属性值为引用数据类型的话,就会影响其他所有的实例对象 person1.friend.push('zhaoliu'); console.log(person1.friend);//["zhangsan", "lisi", "zhaoliu"] console.log(person2.friend);//["zhangsan", "lisi", "zhaoliu"] //原型模式最大的问题是由其共享的本质导致的,而引用数据类型的储存方式造成了实例化对象之间的相互影响。 //为了解决这个问题,提出构造函数和原型混合的模式。 //4.构造函数和原型混合模式 function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.friend = ['zhangsan', 'lisi']; } Person.prototype.sayName = function () { alert(this.name); }; var person1 = new Person("zhangsan", 18, "frontend"); var person2 = new Person("lisi", 20, "frontend"); //如果想改写属性,可直接在实例上添加属性值; person1.name = 'jerry'; console.log(person1.name); console.log(person2.name); // 如果该属性值为引用数据类型的话,因为引用数据类型的属性是在构造函数中,所以实例间数据不会影响 person1.friend.push('zhaoliu'); console.log(person1.friend);//["zhangsan", "lisi", "zhaoliu"] console.log(person2.friend);//["zhangsan", "lisi"] //5:为了更好的体现封装性,可在构造函数中初始化原型,同时又保持使用构造函数和原型的优点; //通过检查某个应该存在的方法是否有效,来决定是否需要初始化原型 function Person(name, age, job) { this.name = 'tom'; this.age = 16; this.job = 'frontend'; this.friend = ['zhangsan', 'lisi']; if (typeof this.sayName != "function") { Person.prototype.sayName = function () { alert(this.name); } } } var person1 = new Person("zhangsan", 18, "frontend"); // jerry var person2 = new Person("lisi", 20, "frontend"); // tom person1.friend.push('zhaoliu'); console.log(person1.friend);//["zhangsan", "lisi", "zhaoliu"] console.log(person2.friend);//["zhangsan", "lisi"] </script> </html>
js中创建对象的几种方式
最新推荐文章于 2020-10-07 10:29:27 发布
615

被折叠的 条评论
为什么被折叠?



