欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

原型以及原型链的学习随笔

程序员文章站 2022-03-06 10:23:38
一 原型: 1 定义:原型是function对像的一个属性,他定义了构造函数制造出的对象的公共祖先; 通过该构造函数产生的对象,可以继承该原型的属性和方法。 原型也是对像。prototype; Person.prototype.name = 'jams'; function Person(){ } ......


一 原型: 

1 定义:原型是function对像的一个属性,他定义了构造函数制造出的对象的公共祖先;

通过该构造函数产生的对象,可以继承该原型的属性和方法。

原型也是对像。prototype;

person.prototype.name = 'jams';

function person(){

 

}

var person = new person();

当打印:console.log(person.name)时,会先从函数中找看下有没有这个属性值,如果没有就去原型prototype中找;

因此,这时候打印出来的值为:jams 

prototype 是函数对象默认的属性,可以增删改查; 

 

2 利用原型特点和概念,可以提取共有属性;

3对象如何查看原型——>隐式属性:__proto__

  __proto__ 中存放的就是构造函数的原型

相当于:在函数中隐藏了一段代码: var  this = {

__proto__: person.prototype

  举个例子:

var obj = { name: 'a'}

var obj1 = obj;

 obj = {name : 'b'}

console.log(obj1.name);// 输出的值为 a 

console.log(obj.name);// 输出的值为 b 
  对比:

  var obj = { name: 'a'}

var obj1 = obj;

   obj.name ='b'

console.log(obj1.name);// 输出的值为 b 

console.log(obj.name);// 输出的值为 b 

 

  原因: 当你修改obj.name 时,修改的是原型中的值,当你重新附值给obj时(obj={name:'b'}),相当于重新定义了obj这个变量;

换个理解方式为,obj.name 是一个指针,而obj 是一个变量; 

 

 

 

4 对象如何查看对象的构造函数:constructor;

constructor 是默认自带的一个属性,他的值指向原函数;

二 原型链: 

1如何构成原型链: 一级一级往上找;

 举个栗子: 

 grand.prototype.lastname = 'a';

function grand(){

  var grand = new grand();

 

father.prototype = grand;

function father() {

this.name =  ' b '; 

var father = new father(); 

 

  son.prototype = father;

function son(){

this.hobbit = 'smoke';

 

}

var son = new son(); 

 

  console.log( son.name );  // b

console.log(son.lastname); // a

 

  2 原型链上属性的增删改查:跟原型上的增删改查基本一致,其中删除:delete 只能通过原型prototype 才能删除原型的值;

 

 

person.prototype = {

name = 'a',

sayname : function(){

  console.log(this.name);

}

function person(){ 

  this.name = 'b';

  var person = new person();

  sayname 里面的this指向是,谁调用的这个方法,this指向谁;

  所以最终结果person.sayname() 的值为b

而person.prototype.sayname() 的值为a 

 

  3绝大多数对象的最终都会继承自object.prototype

但不是所有的对象都可以继承,特例:object.creat()原型;

例如:object.creat(null) ,该对象没有prototype原型;

 

4原型链的重写:

例如常见的如下原型链就是经常被重写试用的,当然自己定义的原型同样也是可以被重写 

object.prototype.tostring

number.prototype.tostring

array.prototype.tostring

boolean.prototype.tostring

string.prototype.tostring 

 

(题外话:js 有个小bug:

控制台运算:0.14*100,去看下运算结果: 14.000000000000002  这是js精度不准问题导致的;

 解决方法:小数先乘以100然后向下取整或向上取整。如果利用保留两位有效数字的方法tofixed()再乘以100是不准确的;

math.random() 会产生一个(0,1)的随机数 

tofixed() 保留两位有效数字 

math.tofloor() 向下取整

math.toceil() 向上取整; 

 

var num =math.tofloor(math.random()*1000);  // 获取0-100的随机数;

 ) 

 

 

三 call、apply

 call、apply的作用:可以借助别人的函数实现自己的功能 

call 可以该表this指向

例如:

function person(name,age){

 //this == obj;

this.name = name;

this.age = age; 

var person = new person( 'a' ,100);

var obj = {}

 

person.call(obj, 'b' ,300);

 这句话的意思就是调用person的方法,然后将相关值附值给obj,使得obj有相关参数属性值;

 执行结果:obj

 

{name: "b", age: 300}

这样的好处,借用person的方法来封装了obj; 

 

例如:

function person(name,age,sex){

this.name  =  name;

this.age = age;

this.sex = sex; 

function otherinformation(tel,grade){

this.tel = tel;

 

this.grade = grade; 

function student(name,age,sex,tel,grade) {

person.call(this,name,age,sex);


otherinformation.call(this,tel,grade)

}

var student = new student('asd',123,'male',129,2018) ;

 

 输出结果:

student {name: "asd", age: 123, sex: "male", tel: 129, grade: 2018}

 

call与apply的区别:后面传的参数形式(或者传参列表)不同; 

apply 只能传两个参数,一个是this,另一个是数组,例如: person.apply(this,[name,age,sex]);

 

 

 

转载请注明出处