资讯专栏INFORMATION COLUMN

[JS相关的记录01] 那什么来面对你,面向对象编程(__proto__,prototype,con

raledong / 2187人阅读

摘要:首先定义空函数这个不用解释,然后把这个空函数的原型指向为的原型,然后再把的原型指向这个新的对象,一个完美传递最后,在把原型的构造方法定义成华丽的转身,结果如下结果还是不对,于是我又在大神的肩膀上垫了一下脚。

总是听说面向对象,类,继承,__proto__,prototype,constructor.......于是乎小整理一下。

首先说,JS里的继承是怎么弄的呢?

首先创建类(Person)

</>复制代码

  1. var Person = {
  2. male: 0,
  3. age:0,
  4. name:"nothing",
  5. say:function(){
  6. console.log("Hello World");
  7. }
  8. }

如何创建一个人呢?

</>复制代码

  1. var createPerson = function(){
  2. return Object.create(Person);
  3. }

创建学生

</>复制代码

  1. var Student = createPerson();
  2. Student.say() //Hello World
  3. Student.__proto__ === Person //true
  4. Student.constructor === Person //Student的构造器还是Object

从这个可以看出什么呢?可以看出所谓的继承,就是下面的代码而已:

</>复制代码

  1. SSSSS.__proto__ = BBBBB

但是呢?也没有prototype啥关系嘛,因为压根就和他没关系,好像也不太好,换一种写法好了。

</>复制代码

  1. function Person (props){
  2. this.name = props.name || "nothing";
  3. this.male = props.male || 0;
  4. this.age = props.age || 0;
  5. this.say = function(){
  6. console.log("Hello world!");
  7. }
  8. }

继续创建student

</>复制代码

  1. var Student = new Person();
  2. Student.__proto__ === Person.prototype //true
  3. Student.constructor === Person //true
  4. Student.say() //Hello world!

从上面代码可以看出,Student继承了Person.
如果我们想改变一下呢?

</>复制代码

  1. Student.say = function(){
  2. console.log("Hello teacher, my name is " + this.name);//Hello teacher, my name is nothing
  3. }

那好,再创建一个coder类

</>复制代码

  1. var Coder = new Person();
  2. Coder.say(); //Hello world!

这个不错嘛,这样在想创建Coder的子类,js和html,那就修改一下代码

</>复制代码

  1. function Coder (props){
  2. Person.call(this,props);
  3. this.tip = props.tip?props.tip.toUpperCase():"";
  4. this.intro = function(){
  5. console.log("I know "+(this.tip?this.tip:"nothing"));
  6. }
  7. this.say= function(){
  8. console.log("hello, my name is " + this.name);
  9. }
  10. }
  11. var JSer = new Coder({
  12. name:"Tony",
  13. age:26,
  14. tip:"js"
  15. });
  16. var htmler = new Coder({
  17. name:"Jermy",
  18. age:26,
  19. tip:"html"
  20. });
  21. JSer.say(); //hello, my name is Tony
  22. htmler.say(); //hello, my name is Jermy
  23. JSer.intro(); //I know JS
  24. htmler.intro();//I know HTML

这样得到了我们想要的结果,验证一下继承关系:

</>复制代码

  1. JSer instanceof Coder; //true
  2. htmler instanceof Coder;//true
  3. Coder instanceof Person;//false

这样就不好了,为什么不是继承关系呢?查看一下Coder情况如何?

</>复制代码

  1. Coder.__proto__ === Person.prototype; //false
  2. Coder.__proto__ //function () { [native code] }

看来问题就出在这里,写一个中间函数补充一下?

</>复制代码

  1. var pass = function(child,parent){
  2. var F = function(){};
  3. F.prototype = Parent.prototype;
  4. Child.prototype = new F();
  5. Child.prototype.constructor = Child;
  6. }

为了实现这一点,参考道爷(就是发明JSON的那个道格拉斯)的代码,中间对象可以用一个空函数F来实现,大神写的代码,就是特么让人深思。
仔仔细细想了下,我个人是这么理解的。
首先定义空函数这个不用解释,然后把这个空函数的原型指向为Parent的原型,然后再把Child的原型指向这个新的F对象,一个完美传递;
最后,在把Child原型的构造方法定义成Child;
华丽的转身,结果如下:

</>复制代码

  1. function Coder (props){
  2. Person.call(this,props);
  3. this.tip = props.tip?props.tip.toUpperCase():"";
  4. this.intro = function(){
  5. console.log("I know "+(this.tip?this.tip:"nothing"));
  6. }
  7. this.say= function(){
  8. console.log("hello, my name is " + this.name);
  9. }
  10. }
  11. var pass = function(Child,Parent){
  12. var F = function(){};
  13. F.prototype = Parent.prototype;
  14. Child.prototype = new F();
  15. Child.prototype.constructor = Child;
  16. }
  17. pass(Coder, Person);
  18. var JSer = new Coder({
  19. name:"Tony",
  20. age:26,
  21. tip:"js"
  22. });
  23. var htmler = new Coder({
  24. name:"Jermy",
  25. age:26,
  26. tip:"html"
  27. });
  28. JSer.say(); //hello, my name is Tony
  29. htmler.say(); //hello, my name is Jermy
  30. JSer.intro(); //I know JS
  31. htmler.intro();//I know HTML
  32. JSer instanceof Coder; //true
  33. htmler instanceof Coder;//true
  34. Coder instanceof Person;//false

结果还是不对,于是我又在大神的肩膀上垫了一下脚。

</>复制代码

  1. var pass = function(Child,Parent){
  2. var F = function(){};
  3. F.prototype = Parent.prototype;
  4. Child.__proto__ = new F();
  5. Child.__proto__.constructor = Child;
  6. }

结果就正确了......

又查了一下,总结一下:

所有的对象都有__proto__属性,该属性对应该对象的原型.

所有的函数对象都有prototype属性,该属性的值会被赋值给该函数创建的对象的_proto_属性.

所有的原型对象都有constructor属性,该属性对应创建所有指向该原型的实例的构造函数.

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

虽说弄懂了些表面的东西,实际上最主要的原因还是没明白,那就是原型链到底有什么用呢?

好了,以上就是今天总结的一些内容,希望相互学习帮助,能够在未来更好的工作生活。
信息来源:

(↓相关一些对我帮助很大,Git的学习就是在这里看的,说的很详细也很生动↓)
廖雪峰JavaScript教程
JS原型、原型链深入理解
深入分析js中的constructor 和prototype

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/83121.html

相关文章

  • 浅谈面向对象javascript几个特性

    摘要:中的和是一门很灵活的语言,尤其是。即然是面向对象的编程语言,那也是不可或缺的。在中,永远指向的是他的调用者。定义是存在于实例化后对象的一个属性,并且指向原对象的属性。我们在扩展的时候,同时父类也会有对应的方法,这很显然是一个很严重的问题。 javascript中的this和new javascript是一门很灵活的语言,尤其是function。他即可以以面向过程的方式来用,比如: f...

    JayChen 评论0 收藏0
  • 再谈JavaScript面向对象思想及继承

    摘要:面向对象中有三大特征,封装,继承,多态。这不仅无法做到数据共享,也是极大的资源浪费,那么引入对象实例对象的属性指向其构造函数,这样看起来实例对象好像继承了对象一样。实例对象的原型指向其构造函数的对象构造器的指向。 前言 为什么说是再谈呢,网上讲解这个的博客的很多,我开始学习也是看过,敲过就没了,自以为理解了就结束了,书到用时方恨少啊。实际开发中一用就打磕巴,于是在重新学习了之后分享出来...

    svtter 评论0 收藏0
  • 深入浅出面向对象和原型【番外篇——重新认识new】

    摘要:前言我们在深入浅出面向对象和原型概念篇在这篇文章中了解到了如何使用解决重复创建浪费内存的问题,其中的关键就是,那么这篇文章让我们来重新了解的前世今生一个苦逼年级主任的故事开学啦高一年级主任龚主任需要为全年级每一位理科班新生录入学号并为每一位 前言 我们在深入浅出面向对象和原型【概念篇2】在这篇文章中了解到了如何使用new Function解决重复创建浪费内存的问题,其中的关键就是new...

    Apollo 评论0 收藏0
  • 理解JavaScript核心知识点:原型

    摘要:首先,需要来理清一些基础的计算机编程概念编程哲学与设计模式计算机编程理念源自于对现实抽象的哲学思考,面向对象编程是其一种思维方式,与它并驾齐驱的是另外两种思路过程式和函数式编程。 JavaScript 中的原型机制一直以来都被众多开发者(包括本人)低估甚至忽视了,这是因为绝大多数人没有想要深刻理解这个机制的内涵,以及越来越多的开发者缺乏计算机编程相关的基础知识。对于这样的开发者来说 J...

    iKcamp 评论0 收藏0
  • JS对象(1)重新认识面向对象

    摘要:对象重新认识面向对象面向对象从设计模式上看,对象是计算机抽象现实世界的一种方式。除了字面式声明方式之外,允许通过构造器创建对象。每个构造器实际上是一个函数对象该函数对象含有一个属性用于实现基于原型的继承和共享属性。 title: JS对象(1)重新认识面向对象 date: 2016-10-05 tags: JavaScript 0x00 面向对象 从设计模式上看,对象是...

    superw 评论0 收藏0

发表评论

0条评论

raledong

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<