JavaScript学习总结--创建对象(3_原型)

当我们创建一个函数时,这个函数都会有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,这个对象包含了特定类型的所有实例共享的属性和方法

就象这样

仔细观察我们可以发现,数组对象Array的prototype属性指向一个对象,而这个对象包含了很多属性和方法,其中就有我们常见的length属性,以及pop()、push()、shift()等方法

那么也就是说,这些属性和方法被定义在Array的prototype上,为所有的实例对象(数组)共享

所以我们在定义数组之后就可以使用这些属性和方法,且每一个数组都引用自这个原型上的属性和方法,在原型上的属性是共享的,所以实例化一个新数组只会隐含指向这个原型对象的指针(__proto__)而不是完全复制一份

所以我们得知

var aArr=new Array();
console.log(aArr.__proto__==Array.prototype);

在JavaScript内置对象Array上有一个prototype属性,指向了包含对所有数组共享属性和方法的一个对象,而通过Array实例化一个新数组,这个数组也有一个__proto__属性,也指向这个对象,这个对象在JavaScript中就叫做原型

那么同样的,Date对象也会有一个prototype属性,指向了包含对所有日期对象共享属性和方法的一个对象,通过Date对象实例化的一个日期对象也会有一个__proto__属性指向他们的原型

前面我们说到,构造函数封装对象的本质就是模仿JavaScript的内置对象,那么既然内置对象共享的属性和方法都存放在这个prototype上,我们自己创建的对象也可以吗?

上一节我们有一段代码是这样的

person_01.sayName==person_02.sayName;    //false

那么我们使用原型来创建对象看看会不会有什么不同

function Person(name,age,job){
  this.name=name;
  this.age=age;
  this.job=job;
}
Person.prototype.sayName=function(){
  //这样可以把方法写在原型上
  console.log(this.name);
}

//书上会绕一大个弯先把所有属性和方法都写在原型上,再讲某些属性不能共享之类的,这里跳过

var person_01=new Person("Sakura",22,"前端开发");
var person_02=new Person("Misaka",20,"网页设计");

这时我们再来看看两个实例化对象的sayName方法是不是相等

person_01.sayName==person_02.sayName;    //true
//同时可以得知
person_01.__proto__==Person.prototype;    //true
person_01.__proto__==person_02.__proto__;    //true

同时在prototype对象上也有一个无关紧要的属性constructor属性,这个属性指向原型所属的构造函数(可以认为是指向它所属的类型)

console.log(Person.prototype.constructor);
/*
function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
}
*/
//因为实例化对象的__proto__属性也指向原型对象,那么
console.log(person_01.__proto__.constructor==Person.prototype.constructor);        //true

JavaScript实例化对象在调用属性时,首先会在构造函数内部查找属性,如果有则用这个属性,如果没有则在原型上查找

我们知道person_01的constructor属性实际实在它的原型上,构造函数内部找不到constructor属性,所以它会继续往上在原型中查找,所以

console.log(person_01.constructor==Person.prototype.constructor);  

如何判断一个属性或方法在原型还是在构造函数内部(实例属性)呢?

我们使用hasOwnProperty方法

console.log(person_01.hasOwnProperty("name"));    //true

hasOwnProperty方法实际上是判断属性是否在构造函数内,如果在构造函数内则返回true;如果在原型中则返回false

同时有一个in操作符,可以判断某个对象是否包含某一个属性,无论在原型还是在构造函数中

console.log("name" in person_01);        //true

所以我们可以结合这两个方法的结果来判断某个属性是否在原型中

待续

...

时间: 2024-10-10 08:01:00

JavaScript学习总结--创建对象(3_原型)的相关文章

JavaScript学习总结--创建对象(5_还是原型)

这咋还没完没了呢?我们之前使用原型+构造函数混合模式创建对象时是这样子写的 function Person(name,age){ this.name=name; this.age=age; } Person.prototype.sayName=function(){ console.log(this.name); } var person1=new Person('Sakura',22); person1.sayName(); 很明显的一个问题就是,这段代码创建的对象似乎没有我们想象中那么完美,

JavaScript学习总结--创建对象(2)

由于网络原因,所以写了一半就赶紧发了... 书接上回 既然工厂模式创建的对象不属于任何类型,我们知道JavaScript中实际上是没有类(class)这个概念的,所以我们需要创建一个伪类,这就用到了构造函数模式 2.构造函数模式 所谓构造函数,就是将工厂模式改写一下,使用new关键字,模仿JavaScript内置对象的形式来创建对象 我们知道JavaScript的内置对象(Array.Function等),创建时一般是 var aArr=new Array()的写法,且内置对象的首字母为大写,所

JavaScript学习总结--创建对象(6_其他方法)

前面我们一共介绍了四种方法用来封装对象(工厂,构造模式,原型模式,构造+原型),并且重点对构造函数+原型模式做了一些改进,使之更加完美,那么除了这几种方法, 还有两种方式用来封装对象,还是那句话,选择适合自己的(其实每种方法都各有利弊,在我刚开始学习时总感觉就是拆东墙补西墙). 首先来看第一种方法 function Person(name,age){ var o=new Object(); o.name=name; o.age=age; o.sayName=function(){ console

JavaScript学习笔记-创建对象之设计模式

<!DOCTYPE html><html> <head>  <title>浏览器对象</title>    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>    </head> <body>    <script>         <!--创建对象之普通模式--&g

JavaScript学习总结--创建对象

ECMA-262定义的对象是:无序属性的集合,其属性可以包含基本值.对象或者函数 说白了就是把一组特定的变量和方法封装起来 那么我们先创建一个对象 var person=new Object(); person.name="Sakura"; person.age=22; person.job="前端开发"; person.sayName=function(){ console.log(this.name); } //当一个变量被封装在一个对象中时,这个变量就可以称为

JavaScript构造函数+原型创建对象,原型链+借用构造函数模式继承父类练习

虽然经常说是做前端开发的,但常常使用的技术反而是JQuery比较多一点.在JavaScript的使用上相对而言少些.尤其是在创建对象使用原型链继承上面,在项目开发中很少用到.所以今天做个demo练习一下,以后忘记了也可以照搬一下. 说明一下: 1. Demo中使用的是构造函数+原型模式创建的对象.构造函数中存储对象实例使用的属性,原型模式增加实例使用的方法. 2. Demo中的继承分为两个方面.一个是属性继承,使用的是借用构造函数模式 call()方法.另一个是方法继承,这个就是使用原型方式继承

JavaScript学习--Item15 prototype原型和原型链详解

用过JavaScript的同学们肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都会有一个prototype属性,可以为其添加函数供实例访问,其它的就不清楚了,最近看了一些 JavaScript高级程序设计,终于揭开了其神秘面纱. 每个函数都有一个prototype属性,这个属性是指向一个对象的引用,这个对象称为原型对象,原型对象包含函数实例共享的方法和属性,也就是说将函数用作构造函数调用(使用new操作符调用)的时候,新创建的对象会从原型对象上继承属性和

JavaScript学习笔记(三)——this、原型、javascript面向对象

一.this 在JavaScript中this表示:谁调用它,this就是谁. JavaScript是由对象组成的,一切皆为对象,万物皆为对象.this是一个动态的对象,根据调用的对象不同而发生变化,当然也可以使用call.apply修改this指向的对象.它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用 1.1.JavaScript中函数与方法的区分 在面向过程的语言中我们习惯把完成某个特定功能的代码块称为“函数”或“过程”,当然过程一般没有返回值.在面向对象语言中我们把对象的功能

JavaScript学习总结(十七)——Javascript原型链的原理

一.JavaScript原型链 ECMAScript中描述了原型链的概念,并将原型链作为实现继承的主要方法.其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法.在JavaScript中,用 __proto__ 属性来表示一个对象的原型链.当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止! 比如现在有如下的代码: 扩展Object类,添加Clone和Extend方法 1 /*扩展Object类,添加Clone,JS实现克隆的方法*/ 2 Ob