javascript之创建对象
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("wuyu", 20, "enginneer"); var person1 = createPerson("zhangsan", 29, "tearcher");
function Person(name, age, job) {this.name = name;this.age = age;this.job = job;this.sayName = function(){alert(this.name);}}var person1 = new Person("wuyu", 20, "enginneer");var person2 = new Person("zhangsan", 29, "tearcher");
alert(person1.constructor == Person); //true alert(person2.constructor == Person); //true
对象的consctructor属性最初是用来标识对象类型的,但是检测对象类型还是使用instanceof检测对象类型比较可靠些。这例子中创建的所有对象既是Object的实例,同时也是Person的实例.如下:
alert(person1 instanceof Object); //truealert(person1 instanceof Person); //truealert(person2 instanceof Object); //truealert(person2 instanceof Object); //true
function Person(name,age,job){this.name=name;this.age=age;this.job=job;this.sayName=function(){alert(this.name);};}//当作构造函数使用var person = new Person("wuyan",20,"enginner");person.sayName(); //wuyan//作为普通函数使用Person("zhangsan",27,"Doctor");window.sayName(); //zhangsan//在另一个对象的作用域中调用(将Person()放入o作用域中调用)var o = new Object();Person.call(o,"Kristen",25,"Nuese");o.sayName(); //Kristen
构造函数模式虽然好用,但也并非没有缺点。最大的问题就是每个方法都要在每个实例上重新创建一遍。比如上面的person1和person2都有一个sayName()的方法,但那两个方法不是同一个Function的实例。ECMAScript中的函数是对象,因此每定义一个函数,也就是实例化了一个对象。创建两个实现的功能完全相同的Function实例真没必要,大可通过把函数定义转移到构造函数外部来解决这个问题。如下:
function Person(name,age,job){this.name=name;this.age=age;this.job=job;this.sayName= sayName;}functin sayName = function(){alert(this.name);};var person1 = new Person("wuyu", 20, "enginneer");var person2 = new Person("zhangsan", 29, "tearcher");
将sayName转移到构造函数外部,而在构造函数内部我们将sayName属性设置成了全局的sayName函数。这样一来,sayName包含的是一个指向函数的指针,因此person1 和person2就共享了在全局作用域中的同一个sayName()函数。可是,对象需要定义很多方法,那么就要定义很多全局函数,于是我们这个自定义的引用类型就丝毫没有封装性可言了。这些问题我们可以使用原型模式来解决。
function Person() {}Person.prototype.name = "wuyan";Person.prototype.age = 20;Person.prototype.job = "engineer";Person.prototype.sayName = function(){alert(this.name);}var person1 = new Person();person.sayName(); //wuyanvar person2 = new Person();person2.sayName(); //wuyanalert(person1.sayName == person2.sayName); //true
alert(Person.prototype.isPrototypeOf(person1)); //truealert(Person.prototype.isPrototypeOf(person2)); //true
虽然可以通过对象实例访问保存在原型中的值,但去不能通过对象实例重写原型中的值。如下:
function Person() {}Person.prototype.name = "wuyan";Person.prototype.age = 20;Person.prototype.job = "engineer";Person.prototype.sayName = function(){alert(this.name);}var person1 = new Person();var person2 = new Person();person1.name = "poxiao";alert(person1.name); //poxiao--->来自实例,在搜索name属性时,在对象实例本身就可以 //找到,就不 必再搜索原型了alert(person2.name); //wuyan--->来自原型//当然,我们可以使用delete操作符删除实例属性,这样就可以重新访问到原型中的属性了。如下:function Person() {}Person.prototype.name = "wuyan";Person.prototype.age = 20;Person.prototype.job = "engineer";Person.prototype.sayName = function(){alert(this.name);}var person1 = new Person();var person2 = new Person();person1.name = "poxiao";alert(person1.name); //poxiao--->来自实例alert(person2.name); //wuyan--->来自原型delete person1.name;alert(person1.name); //wuyan--->来自原型
使用hasOwnProperty()方法可以检测一个属性是存在于实例中,还是存在于原型中。这个方法(它是从Object继承来的)只在给定属性存在于对象实例中时,才会返回true。如下:
function Person() {}Person.prototype.name = "wuyan";Person.prototype.age = 20;Person.prototype.job = "engineer";Person.prototype.sayName = function(){alert(this.name);}var person1 = new Person();var person2 = new Person();alert(person1.hasOwnProperty("name")); //falseperson1.name = "poxiao";alert(person1.name); //poxiao-->来自实例alert(person1.hasOwnProperty("name")); //truealert(person2.name); //wuyan--->来自原型alert(person2.hasOwnProperty("name")); //falsedelete person1.name;alert(person1.name); //wuyan--->来自原型alert(person1.hasOwnProperty("name")); //false
function Person(){}Person.prototype.name="wuyan";Person.prototype.age=20;Person.prototype.job="engineer";Person.sayName=function(){alert(this.name);}var person1=new Person();var person2=new Person();alert(person1.hasOwnProperty("name")); //falsealert("name" in person1); //trueperson1.name="poxiao";alert(person1.name); //poxiao来自实例alert(person1.hasOwnProperty("name")); //truealert("name" in person1); //truealert(person2.name); //wuyan来自原型alert(person2.hasOwnProperty("name")); //falsealert("name" in person2); //truedelete person1.name;alert(person1.name); //wuyan来自原型alert(person1.hasOwnProperty("name")); //falsealert("name" in person1); //truealert(person1.hasOwnProperty("qqqq")); //falsealert("qqqq" in person1); //false//同时使用hasOwnProperty()方法和in操作符,就可以确定该属性到底是存在于对象中, //还是存在于原型中。如下:function hasPrototypeProperty(object, name){return !object.hasOwnProperty(name) && (name in object) ;}
在使用for-in循环时,返回的是所有能够通过对象访问的、可枚举的(enumerated)属性,其中既包括存在于实例中的属性,也包括存在于原型中的属性。根据规定,所有开始人员定义的属性都是可枚举的(除ie8及更早版本)。如:
var o={toString:function(){return "My Object";} }for (var prop in o){if(prop == "toString"){alert("Found toString"); //在IE中不会显示} }
function Person() {}Person.prototype = {name : "wuyan",age : 20,job : "engineer",sayName : function() {alert(this.name);}}
function Person() {}Person.prototype = {constructor : Person,name : "wuyan",age : 20,job : "engineer",sayName : function() {alert(this.name);}}
function Person() {}var friend = new Person();Person.prototype = {constructor : Person,name : "wuyan",age : 20,job : "enginner",sayName : function() {alert(this.name);}};friend.sayName(); //error
function Person() {}Person.prototype = {constructor : Person,name : "wuyan",age : 20,job : "engineer",friends : ["poxiao", "wyl"],sayName : function() {alert(this.name);}};var person1 = new Person();var person2 = new Person();person1.friends.push("wx");alert(person1.friends); //poxiao,wyl,wxalert(person2.friends); //poxiao,wyl,wxalert(person1.friends === person2.friends); //true 问题出来了,person1结 //交了新朋友意味着person2也必须结交这个朋友
function Person(name ,age ,job){this.name = name;this.age = age;this.job = job;this.friends = ["poxiao", "wyl"];}Person.prototype = {constructor : Person,sayName: function() {this.name;}}var person1 = new Person("wuyan", 20, "engineer");var person2 = new Person("shaobo", 26, "teacher");person1.friends.push("wyl");alert(person1.friends); //poxiao,wyl,wylalert(person2.friends); //poxiao,wylalert(person1.friends === person2.friends); //falsealert(person1.sayName=== person2.sayName); //true
这种构造函数与原型混合的模式,是目前在ECMAScript中使用最广泛、认同度最高的一种创建自定义类型的方法。
function Person(name , age ,job) {//属性this.name = name;this.age = age;this.job = job;//方法if(typeof this.sayName != "function") {Person.prototype.sayName = function(){alert(this.name);};}}var friends = new Person("wuyan", 20, "engineer");friends.sayName();
function Person(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 friend = new Person("wuyan", 20, "engineer");friend.sayName(); //wuyan
function Person(name, age, job) {//创建要返回的对象var o = new Object();//可以在这定义私有变量和函数//添加方法o.sayName = function() {alert(name);}return o;}var friend = Person("wuyan", 20, "engineer");friend.sayName(); //wuyan
javascript之创建对象相关推荐
- JavaScript之创建对象的模式
使用Object的构造函数可以创建对象或者使用对象字面量来创建单个对象,但是这些方法有一个明显的缺点:使用相同的一个接口创建很多对象,会产生大量的重复代码. (一)工厂模式 这种模式抽象了创建具体对象 ...
- 【JavaScript】创建对象的三种方式
JavaScript创建对象的三种方式 1.调用系统的构造函数创建对象2.自定义构造函数创建对象(结合第一种和需求通过工厂模式创建对象)3.字面量的方式创建对象 一.调用系统的构造函数创建对象 举个栗 ...
- JavaScript:创建对象(原型模式和构造函数模式)
JavaScript:对象 一.理解对象 var person = {}Object.defineProperty(person,'name',{writable:false,value : 'Nik ...
- JavaScript 中创建对象的方法(读书笔记思维导图)
面向对象(Object-Oriented, OO)的语言有一个标志,那就是它们都有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象.而 ECMAScript 中没有类的概念,所以我们可以使用 ...
- javaScript中创建对象和Java创建对象的区别
1. 前言 作为Java 帝国的未来继承人,Java小王子受到了严格的教育, 不但精通Java语言.Java虚拟机.java类库和框架,还对各种官方的Java规范了如指掌. 近日他听说一个叫做Java ...
- JavaScript中创建对象的方法
1. 工厂模式 用函数来封装以特定接口创建对象的细节.但是这种方法无法解决确定对象类型的问题. function createPerson(name,age,job){var o = new Obje ...
- Javascript之创建对象(原型模式)
我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,它的用途是包含可以有特定类型的所有实例共享的属性和方法. prototype就是通过构造函数而创建的那个对象 ...
- JavaScript对象创建对象的四种方式
1.字面量的方式 2.调用系统的构造函数 3.自定义构造函数的方式 4.工厂模式创建对象 <!DOCTYPE html> <html lang="en"> ...
- JavaScript中创建对象方法
1.直接创建法: 该方法简单直接,却不能直接量产 2.工厂模式---利用函数创建对象: 工厂模式解决了无法量产的问题,但是它自身的弊端就是无法 明确对象类型,比如上例中若用instanceof分别检测 ...
最新文章
- Scrum Master是什么?Scrum Master的职责是什么?和PM又有哪些区别?
- 挪动以太坊:比特币现金的新功能使其成为智能合约竞争者
- SpringBoot集成Mybatis动态多数据源后,MybatisPlus的IPage失效的问题解决方案
- interface接口_golang 基础(Four) 接口进阶
- 深度剖析Kubernetes API Server三部曲 - part 1
- CodeForces - 343D Water Tree(树链剖分+线段树)
- RabbitMQ之mandatory和immediate
- 一线大厂为什么对免费的开源项目这么热衷?
- SQL语句使用总结(一)
- 手机APP移动应用开发
- 卧槽!华为工程师总结的Java笔记,太优秀了!
- java代码split分割数字类
- Java项目开发管理工具-Maven基础
- UBUNTU完美运行TM,RTX,MSOffice,迅雷
- 单片机节日彩灯c语言,单片机节日彩灯控制器的设计Proteus仿真
- OSG正二十面体均分球面
- linux 达人养成计划 II笔记
- Netty下的消息群发
- 在TCP端口筛选只允
- APK部署手机上出现闪退现象
热门文章
- mysql库提示 Table ‘xxx’ is marked as crashed and should be repaired
- Dgraph使用总结
- 密室NPC的演技吊打流量明星
- LeetCode每日一题——380. O(1) 时间插入、删除和获取随机元素
- 【计算机网络】【运输层-4】
- JAVA导出Word文档工具EasyWord
- 【Spring Boot】闲聊Spring Boot(一)
- Oracle EBS MRP Forecast预测删除实例脚本
- java写一个web服务器_Java实现web服务器功能(简版) | kTWO-个人博客
- RME 发布 Fireface UFX III 声卡