js的原型和原型链是:
JavaScript是一门基于原型的语言,在软件设计模式中,有一种模式叫做原型模式,JavaScript正是利用这种模式而被创建出来
原型模式是用于创建重复的对象,同时又能保证性能,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。原型模式的目的是用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象,也就是说利用已有的一个原型对象,可以快速地生成和原型对象一样的新对象实例
原型:一个可以被复制(或者叫克隆)的一个类,通过复制原型可以创建一个一模一样的新对象,也可以说原型就是一个模板,在设计语言中更准确的说是一个对象模板
1)原型是定义了一些公用的属性和方法,利用原型创建出来的新对象实例会共享原型的所有属性和方法
实例代码:
// 创建原型 var Person = function(name){ this.name = name; }; // 原型的方法 Person.prototype.sayHello = function(){ console.log(this.name+",hello"); }; // 实例化创建新的原型对象,新的原型对象会共享原型的属性和方法 var person1 = new Person("zhangsan"); var person2 = new Person("lisi"); // zhangsan,hello person1.sayHello(); // lisi,hello person2.sayHello();
2)严格模式下,原型的属性和方法还是会被原型实例所共享的
实例代码:
// 开启严格模式,原型的属性和方法还是会被原型实例所共享的 "use strict"; // 创建原型 var Person = function(name){ this.name = name; }; // 原型的方法 Person.prototype.sayHello = function(){ console.log(this.name+",hello"); }; // 实例化创建新的原型对象,新的原型对象会共享原型的属性和方法 var person1 = new Person("zhangsan"); var person2 = new Person("lisi"); // zhangsan,hello person1.sayHello(); // lisi,hello person2.sayHello();
3)通过原型创建的新对象实例是相互独立的,为新对象实例添加的方法只有该实例拥有这个方法,其它实例是没有这个方法的
实例代码:
// 创建原型 var Person = function(name){ this.name = name; }; // 原型的方法 Person.prototype.sayHello = function(){ console.log(this.name+",hello"); }; // 实例化创建新的原型对象,新的原型对象会共享原型的属性和方法 var person1 = new Person("zhangsan"); var person2 = new Person("lisi"); // zhangsan,hello person1.sayHello(); // lisi,hello person2.sayHello(); // 为新对象实例添加方法 // 通过原型创建的新对象实例是相互独立的 person1.getName = function(){ console.log(this.name); } // zhangsan person1.getName(); // Uncaught TypeError: person2.getName is not a function person2.getName();
4)原型的总结:
所有引用类型都有一个
__proto__
(隐式原型)属性,属性值是一个普通的对象所有函数都有一个prototype(原型)属性,属性值是一个普通的对象
所有引用类型的
__proto__
属性指向它构造函数的prototype
5)函数的原型prototype:函数才有prototype,prototype是一个对象,指向了当前构造函数的引用地址
6)函数的原型对象__proto__:所有对象都有__proto__属性, 当用构造函数实例化(new)一个对象时,会将新对象的__proto__属性指向 构造函数的prototype
7)原型对象和函数的原型的关系
说明:
所有函数的
__proto__
都是指向Function的prototype构造函数new出来的对象
__proto__
指向构造函数的prototype非构造函数实例化出的对象或者对象的prototype的
__proto__
指向Object的prototypeObject的prototype指向null
8)所有的原型对象都会自动获得一个 constructor(构造函数)属性,这个属性(是一个指针)指向 prototype 属性所在的函数(Person)
9)实例的构造函数属性(constructor)指向构造函数 :person1.constructor == Person
10)原型对象(Person.prototype)是 构造函数(Person)的一个实例
11)原型的分类:
隐式原型(_proto_):上面说的这个原型是JavaScript中的内置属性[[prototype]],此属性继承自object对象,在脚本中没有标准的方式访问[[prototype]],但Firefox、Safari和Chrome在每个对象上都支持一个属性_proto_,隐式原型的作用是用来构成原型链,实现基于原型的继承
显示原型(prototype):每一个函数在创建之后,便会拥有一个
prototype
属性,这个属性指向函数的原型对象,显示原型的作用是用来实现基于原型的继承与属性的共享
12)原型的使用方式:
通过给Calculator对象的prototype属性赋值对象字面量来设定Calculator对象的原型
在赋值原型prototype的时候使用function立即执行的表达式来赋值,可以封装私有的function,通过return的形式暴露出简单的使用名称,以达到public/private的效果
原型链
1)原型链:原型链是原型对象创建过程的历史记录,当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的prototype的__proto__
中查找,这样一层一层向上查找就会形成一个链式结构
2)原型设计的问题:当查找一个对象的属性时,JavaScript 会根据原型链向上遍历对象的原型,直到找到给定名称的属性为止,直到到达原型链的顶部仍然没有找到指定的属性,就会返回 undefined
也可以理解为原型链继承时查找属性的过程是先查找自身属性,当自身属性不存在时,会在原型链中逐级查找
3)hasOwnProperty 函数:可以用来检查对象自身是否含有某个属性,返回值是布尔值,当属性不存在时不会向上查找对象原型链,hasOwnProperty是 JavaScript 中唯一一个处理属性但是不查找原型链的函数
4)getOwnPropertyNames 函数:可以获取对象所有的自身属性,返回值是由对象自身属性名称组成的数组,同样不会向上查找对象原型链
5)原型链的小结:
一直往上层查找,直到到null还没有找到,则返回undefined
Object.prototype.__proto__ === null
所有从原型或更高级原型中的得到、执行的方法,其中的this在执行时,指向当前这个触发事件执行的对象
6)JavaScript的原型是为了实现对象间的联系,解决构造函数无法数据共享而引入的一个属性,而原型链是一个实现对象间联系即继承的主要方法
以上就是js的原型和原型链是什么的详细内容,更多请关注Work网其它相关文章!