博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JS原型 原型链
阅读量:6581 次
发布时间:2019-06-24

本文共 3888 字,大约阅读时间需要 12 分钟。

跑在最前面的这段话:

1.JS对象分类:

简单记忆:凡是通过new Function()创建的对象都是函数对象,其他均是普通对象。

2.只有函数对象才有prototype属性,这个属性是一个指针,指向一个对象(通过该构造函数创建实例对象的原型对象),该属性的指向我们就可以叫做“原型”或者“原型对象”,即:

1 function Person() {};2 Person.prototype;3 //constructor:ƒ Person()4 //__proto__:Object
var A = Person.prototype;//将A记做原型对象

3.默认情况下,所有的原型或者原型对象都会自动获得一个constructor(构造函数)属性,该属性(是一个指针)指向该函数的构造函数,即:

1 Person.prototype.constructor == Person

3.js对象均有一个_proto_属性;但_proto_并非是一个规范属性,只是部分浏览器实现了此属性,对应的标准属性是[[Prototype]];

  • 每个对象规定一个私有属性[[prototype]],[[prototype]]所指向的对象也有一个[[prototype]]属性;
  • 但是[[prototype]]语言使用者是无法访问的,不过FirFox的js引擎将其暴露出来,作为公有属性__proto__

4.函数对象和原型对象通过prototype和constructor属性进行相互关联;

5.constructor属性

constructor属性始终指向创建当前对象的构造函数。

1     var arr=[1,2,3]; 2     console.log(arr.constructor); //function Array(){}; 3     var a={}; 4     console.log(arr.constructor);//function Object(){}; 5     var bool=false; 6     console.log(bool.constructor);//function Boolean(){}; 7     var name="hello"; 8     console.log(name.constructor);//function String(){}; 9     var sayName=function(){}10     console.log(sayName.constrctor)//function Function(){}11     12     //通过构造函数创建instance13     function A(){}14     var a=new A();15     console.log(a.constructor);//function A();
1    function Person(name){ 2         this.name=name; 3     } 4     Person.prototype.sayName=function(){ 5         console.log(this.name); 6     } 7      8     var person=new Person("lili"); 9     10     console.log(person.constructor); // function Person(){}11     console.log(Person.prototype.constructor);// function Person(){}12     console.log(Person.constructor); // function Function(){}

 1.构造函数:

1 function Foo(name,age){2   this.name = name;3   this.age = age;4   this.class = 'class-1';5   //return this; //默认有这一行,因此不必自己写6 }7 var f = new Foo('lili',22);

  

2.构造函数的扩展

先抛出一个名词:语法糖

在计算机科学中,语法糖(syntactic sugar)是指编程语言中可以更容易的表达一个操作的语法,它可以使程序员更加容易去使用这门语言:操作可以变得更加清晰、方便,或者更加符合程序员的编程习惯。

简单理解就是代码的一种简洁写法,比如:

1 var a = {} 是 var a = new Object()的语法糖;2 var a = [] 是 var a = new Array()的语法糖3 function Foo(){...}   是var Foo = new Function(){..} 的语法糖

 

3.再抛出五条原型规则:

*所有的引用类型(数组、对象、函数)都具有对象特性,即可自由扩展属性,除了“null”以外;

1 var arr=[];arr.a=100;2 var obj = {};obj.a=200;3 function fn(){};fn.a=300;4 5 console.log(arr);//[a: 100]6 console.log(obj);//{a: 200}7 console.log(fn.a);//200

*所有的引用类型(数组、对象、函数)都有一个__proto__属性(也称隐式原型属性),属性值是一个普通的对象;

1 var arr=[];arr.a=100;2 var obj = {};obj.a=200;3 function fn(){};fn.a=300;4 5 console.log(arr.__proto__);//[constructor: ƒ, concat: ƒ, pop: ƒ, push: ƒ, shift: ƒ, …]6 7 console.log(obj.__proto__);//{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}8 9 console.log(fn.__proto__);//ƒ () { [native code] }

*所有的函数都有一个prototype属性(也称显式原型属性),属性值也是一个普通的对象;

1 var arr=[];arr.a=100; 2 var obj = {};obj.a=200; 3 function fn(){};fn.a=300; 4  5 console.log(arr.__proto__);//[constructor: ƒ, concat: ƒ, pop: ƒ, push: ƒ, shift: ƒ, …] 6  7 console.log(obj.__proto__);//{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …} 8  9 console.log(fn.__proto__);//ƒ () { [native code] }10 11 console.log(arr.prototype);//undefined 没有prototype属性12 13 console.log(fn.prototype);//{constructor: ƒ}

*所有的引用类型(数组、对象、函数)的__proto__属性(即隐式原型属性)指向它的构造函数的" prototype " 属性值(即显显式原型)(===)。

*当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会在它的隐式原型属性__proto__(即它的构造函数的prototype)中一直往上找寻找该属性,但不会查找自身的prototype,(原型链的形成是真正靠_proto_而非prototype属性);这也就是原型链的形成过程(下图中的红色线条表示的过程)

1 //构造函数 2 function Foo(name,age){ 3    this.name=name; 4 } 5 Foo.prototype.alertName = function(){ 6   alert(this.name); 7 } 8 //创建实例 9 var f = new Foo('lili');10 f.printName = function(){11   console.log(this.name);12 }13 //test14 f.printName();//lili15 f.alertName();//lili

实例f中本身有个printName属性,打印出来的console.log(this.name)自然就是创建时传进去的"lili";而alertName属性在构造函数Foo中并没有,于是顺着实列的隐式原型属性__proto__(即其构造函数的prototype属性)找,便找到了alert(this.name)这句。

 

转载地址:http://kqnno.baihongyu.com/

你可能感兴趣的文章
产品研发项目管理软件哪个好?
查看>>
【阿里云北京峰会】一图看懂机器学习PAI如何帮助企业应用智能化升级
查看>>
ansible playbook使用总结
查看>>
Android API中文文档(111) —— MailTo
查看>>
Linux 中如何卸载已安装的软件
查看>>
thinkphp 3.2 增加每页显示条数
查看>>
oracle日常简单数据备份与还原
查看>>
我的友情链接
查看>>
黑马程序员__反射总结
查看>>
Scala学习笔记(5)-类和方法
查看>>
Quartz原理
查看>>
完全卸载oracle|oracle卸载|彻底卸载oracle
查看>>
垃圾收集基础
查看>>
Docker安装及基本命令
查看>>
控制namenode检查点发生的频率
查看>>
Linux存储挂载后,无法正常卸载的解决方法
查看>>
2、递归遍历文件夹下每一个文件
查看>>
Remove auto_increment from Schema Dumps (mysqld...
查看>>
解决activity加上Theme.Translucent.NoTitleBar 页面跳转显示桌面
查看>>
php类库
查看>>