js原型和构造函数

前言

  从应用层面深入理解原型模式和js中的构造函数。

构造函数(constructor)

  js中的任何对象都有自己的构造函数。js中使用字面量声明的普通对象({})或数组([])等子对象本质上都是使用相关的函数做构造调用声明的。

// 等同于 var obj = {};

var obj = new Object();

// 等同于 arr = [];

var arr = new Array();

  获取对象的构造函数:constructor是可读的,在对象上进行普通的属性访问(. / [])即可。

// 这里我们可以看到字面量语法声明的对象本质还是使用Object()构造的。var obj = {};
console.log(obj.constructor); // ƒ Object() { [native code] }

原型

  显式原型prototype属性

    prototype是函数的属性。每个函数被创建之后,都会拥有一个prototype属性,这个属性指向函数的原型对象。

function fn (){}
console.log(fn.prototype); 

    fn.prototype的原型在chrome下的输出。是一个对象,这个对象有一个显式的属性constructor(构造函数),它指向的是构造这个对象的函数。 还有一个隐式的属性,__proto__。

  隐式原型__proto__属性

    __proto__是对象的属性。每个对象被创建的时候都会拥有这个属性,这个属性指向的是,构造这个对象的函数的原型对象。

    访问对象的__proto__属性:IE10以前无法识别__proto__属性,其他浏览器大部分都可以识别,可以输出但无法访问内部信心。ES5提供的Object.getPtotypeOf(obj) 可以获取指定对象的__proto__属性。

function fn (){}
var obj = new fn();
console.log(fn.prototype === Object.getPrototypeOf(obj)); // true

搞清楚prototype/__proto__/constructor之间的区别和联系

  1,所有对象都有自己的构造函数(constructor),和一个隐式的原型属性(__proto__),__proto__指向的是这个对象的构造函数的原型。

  2,所有的函数都有一个prototype属性这个熟悉指向的是构造函数的原型对象。

var obj = {};
// 这里的true不理解的话回头再看一遍之前的小例子,敲一下。理解这个true的话 原型这个部分的应用就没问题了。
console.log(obj.constructor.prototype === Object.getPrototypeOf(obj)); // true

原型链

  原型链就是一个对象作为另一个对象的原型而存,而这个作为别人原型的对象还有自己的原型。

  根对象

    js中的所有对象都拓展于Object.prototype。 它是js中的顶层对象。在它之上没有其他的原型了。

var obj= {};
var objConstructor = obj.constructor;
// Object() 是使用js字面量创建的对象的构造函数。
console.log(objConstructor); // ƒ Object() { [native code] }
// Object.prototype是js中的根对象,在它之上没有其他原型了。
console.log(Object.getPrototypeOf(objConstructor.prototype)); // null

  原型链的形成
    关键就在于让一个对象成为另一个对象的原型。

    Object.create(obj):返回一个把指定参数作为原型的新对象。 

var obj= {name:"obj"};
var newObj = Object.create(obj);
console.log(newObj);

    从chrome下的输出我们可以看到 形成了一个三层的原型链 newObject 中的隐式原型属性__proto__指向了obj,obj是使用字面量创建的普通对象,它本质上是使用Object()创建的。所以它指向的是根对象Object.prototype。

    

原型模式的执行流程

  在对象本身查找要访问的属性和方法,如果没有,就到最近的原型上找,直接原型上没有,就到原型的原型上找,找到就直接返回,结束查找。一直找到Object.prototype上都没有,就返回undefined。

原型模式的应用

  主要有两种,面向对象写法和任务委托写法。面向对象就是使用原型继承,多态都用的很少,使用起来也比较难理解。任务委托是在《你不知道的js》一书中看到的写法,设计上来看比强行面向对象要直观。但现在时代变了,ES6提供了Class语法糖,让面向对象的js程序可读性较好,便于理解。所以只了解一下任务委托写法。

面向对象

  三大特征:封装,继承,多态。

  好处:结构清晰,易维护,易拓展。

基于原型继承的面向对象

  js中是没有传统面向类语言中的类和构造函数的,它使用new关键字配合普通函数模拟了构造函数,使用原型模拟类,让js拥有了继承和多态的能力。

  面向对象写法:定义普通函数做构造调用,在函数的原型上提供实例共享的属性和方法。

function Banner(info){

  this.ele = info.ele;

}

Banner.prototype = {

  constructor:Banner,

  say:function(){

  console.log("我是定义在Banner原型上的方法,由所有Banner构造出来的对象共享!");

  return this;

},

show:function(){

  console.log(this.ele);

  return this;

  }

}

new Banner({

ele:"box"

}).say().show();

  任务委托:将数据和工具对象分开定义,让工具对象作为数据对象的原型。达到数据和逻辑分离,将任务处理委托给其他对象的目的。

var util = {
  say:function(){
    console.log(this.name);
  }
}
var data = Object.create(util);
data.name = "键盘";
data.say(); // 键盘

小结:

  1,每个对象都有自己的构造函数,可以通过constructor属性访问到。

  2,每个对象都有一个隐式原型属性__proto__,可以使用Object.getPrototypeOf(obj)访问。

  3,每个函数都有自己的原型对象,可以通过prototype属性访问。

  4,对象的隐式原型属性(__proto__)指向的就是它的构造函数的原型(prototype)。

  5,所有使用字面量创建的对象,本质上都是使用相关构造器函数构造出来的,函数是(Function()),数组是(Array())等等。

  6,js中的Object是顶层函数它的prototype之上没有其他的原型了。js中所有对象的原型链的顶层几乎都是Object.prototype。

  7,原型链就是对象做为其他对象的原型,的同时还有自己的原型。

  8,原型模式的执行顺序就是首先在对象自有属性中查找,找不到就问原型有没有,原型没有就问原型的原型有没有,直到找到返回或找到顶层原型后返回undefined。

  9,js中的面向对象就是基于原型模式在普通函数的原型上定义共享的属性和方法,达到继承的目的。

原文地址:https://www.cnblogs.com/keliguicang/p/10989478.html

时间: 2024-12-16 21:52:56

js原型和构造函数的相关文章

JS原型与构造函数

面向对象(OOP):  1. 什么是: 程序中都是先用对象来定义数据和功能,再按照逻辑的需要,访问对象中的数据和功能. 2. 为什么: 和现实中人的想法非常接近. 3. 什么是对象: 内存中同时存储多个数据和功能的存储空间 描述现实中一个具体事物的属性和功能的程序结构 事物的属性,会成为对象中的属性 事物的功能,会成为对象中的方法 何时: 今后开始写程序前,都要先用对象,描述好要操作的事物的属性和功能,再按需使用对象的功能,访问对象的属性 如何: 面向对象三大特点: 封装,继承,多态 封装:将一

js原型和构造函数混合模式

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <meta h

js面向对象之组合原型模式+构造函数

我们都知道原型模式构建对象的最大优点就是共享,但是你知道吗,原型模式最大的缺点就是它最大的优点,如果共享的是方法的话使我们期望的一般也不会有什么影响,但是如果牵扯到其他的引用类型的话就会出现麻烦,看如下: //原型的缺点 function Box() {} Box.prototype={ constructor:Box, name:'Lee', age: 20, family:['哥哥','姐姐','妹妹'] } var box1 = new Box(); var box2 = new Box(

JS原型+原型链+设计模式

JavaScript是一种基于对象的语言,JavaScript中的所有对象,都具有prototype属性.prototype属性返回对象的所有属性和方法,所有 JavaScript 内部对象都有只读的 prototype 属性,可以向其原型中动态添加属性和方法,但该对象不能被赋予不同的原型.但是自定义的对象可以被赋给新的原型. 对象分为函数对象和普通对象,区分:凡是通过 new Function() 创建的对象都是函数对象,其他的都是普通对象.(Object ,Function 是JS自带的函数

简单粗暴地理解js原型链--js面向对象编程

简单粗暴地理解js原型链--js面向对象编程 原型链理解起来有点绕了,网上资料也是很多,每次晚上睡不着的时候总喜欢在网上找点原型链和闭包的文章看,效果极好. 不要纠结于那一堆术语了,那除了让你脑筋拧成麻花,真的不能帮你什么.简单粗暴点看原型链吧,想点与代码无关的事,比如人.妖以及人妖. 1)人是人他妈生的,妖是妖他妈生的.人和妖都是对象实例,而人他妈和妖他妈就是原型.原型也是对象,叫原型对象. 2)人他妈和人他爸啪啪啪能生出一堆人宝宝.妖他妈和妖他爸啪啪啪能生出一堆妖宝宝,啪啪啪就是构造函数,俗

JS 原型

<!-- ———————————————— JS原型(prototype) ———————————————————— --> //构造函数模式 (W3C推荐使用) function Person(name,age,sex){ this.name=name; this.age=age; this.sex=sex; this.sayName=function(){ return this.name; } } var person1=new Person("B",11,"

JS 原型链图形详解

JS原型链 这篇文章是「深入ECMA-262-3」系列的一个概览和摘要.每个部分都包含了对应章节的链接,所以你可以阅读它们以便对其有更深的理解. 对象 ECMAScript做为一个高度抽象的面向对象语言,是通过对象来交互的.即使ECMAScript里边也有基本类型,但是,当需要的时候,它们也会被转换成对象. 一个对象就是一个属性集合,并拥有一个独立的prototype(原型)对象.这个prototype可以是一个对象或者null.* 让我们看一个关于对象的基本例子.一个对象的prototype是

深入理解JS原型链与继承

我 觉得阅读精彩的文章是提升自己最快的方法,而且我发现人在不同阶段看待同样的东西都会有不同的收获,有一天你看到一本好书或者好的文章,请记得收藏起来, 隔断时间再去看看,我想应该会有很大的收获.其实今天要讨论的主题,有许多人写过许多精彩的文章,但是今天我还是想把自己的理解的知识记录下来.我在学习 掌握JS原型链和继承的时候,就是看得@阮一峰老师的写的文章,觉得他写的技术类的文章都容易让理解,简明概要,又好理解.他是我学习JS路程里面一个比较佩服的导师,昨天重新看了他写的<Javascript 面向

原型与构造函数

原型与构造函数 一.对象 面向对象的编程语言中有一个非常重要的参数那就是类的概念,通过类我们可以创建出来各种各样的对象,而ECMAscript中没有类的概念,所以他与别的编程语言中处理对象的方式有所不同. ECMA-262中规定了对象:无数属性的集合,其属性可以包含基本值,对象或其他函数 在 JavaScript 中,对象是拥有属性和方法的数据. 属性是与对象相关的值. 方法是能够在对象上执行的动作. 案例1: var people=new Object(); people.name="zhan