构造函数和class的关系,还有面向对象和原型对象,其实很多人都会很困惑这些概念,这是第二次总结这些概念了,之前一次,没有class类,其实了解了构造函数,class也就很容易理解了

一. 构造函数和原型 

  1.function 声明(创造)了一个函数 Person,叫构造函数

  2.原型对象:在声明了一个函数之后,浏览器会自动按照一定的规则创建一个对象,这个对象就叫做原型对象。这个原型对象其实是储存在了内存当中。

  3.在声明了一个函数后,这个构造函数(声明了的函数)中会有一个属性prototype,这个属性指向的就是这个构造函数(声明了的函数)对应的原型对象;原型对象中有一个属性constructor,这个属性指向的是这个构造函数(声明了的函数)。

  所以说:Person(构造函数)的 prototype 指向原型对象,原型对象的 constructor 属性,又指向该构造函数本身

1 function Person(name, age) {
2 this.name = name;
3 this.age = age;
4 }
5 console.log(Person); // 构造函数本身
6 console.log(Person.prototype.constructor); // 指向 构造函数本身
7 Person("范顺", 18);

二. 构造函数使用new来创建对象 

1 function students() {
2
3 }
4
5 var stu = new students();

  1.  stu 是 new students()(构造函数) 创建出来的对象,这个stu对象中是没有prototype属性的,prototype属性只有在构造函数students中有

  2. 但stu(创建出来的对象)有一个__proto__属性,stu调用这个属性可以直接访问到构造函数students的原型对象(也就是说,stu的__proto__属性指向的是构造函数的原型对象)

  所以:stu.__proto__ = students.prototype 都指向原型对象

  3. 我们给原型对象添加属性和方法,那么 new 出来的这个对象就可以访问到该原型对象的属性和方法

 1 function students() {
2 /* 我就是构造函数 */
3 }
4 students.prototype.name="shun"
5 var stu = new students();
6 console.log(stu.__proto__.name); // 访问到原型对象添加的属性
7 console.log(stu.name); // 这样也是能访问到原型对象添加的属性,因为stu本身没有这个name属性,所以说会向stu对象的__proto__ 属性指向的原型对象中找,找到就返回,找不到就往上找,就是原型链
8
9 stu.name = "fan" // 给stu对象添加属性
10 console.log(stu.name); // 访问stu对象的属性

  4. 因为 new 出来的 stu 是一个对象,我们也可以给它直接设置属性,如果找到直接返回值,如果stu对象本身没有这个属性,那么就会向上找stu对象的__proto__属性指向的原型对象中查找,如果查找到则返回。(如果原型中也没有找到,则继续向上找原型的原型 这就是所说的原型链。

  5. 如果通过stu对象添加了一个属性name,则stu对象来说就屏蔽了原型中的属性name。 换句话说:在stu中就没有办法访问到原型的属性name了。
通过stu对象只能读取原型中的属性name的值,而不能修改原型中的属性name的值。 stu.name = “李四”; 并不是修改了原型中的值,而是在stu对象中给添加了一个属性name

<script type="text/javascript">
function students () {
}
// 可以使用students.prototype 直接访问到原型对象
//给students函数的原型对象中添加一个属性 name并且值是 "张三"
students.prototype.name = "张三";
students.prototype.age = 20; var stu = new students();
/*
访问stu对象的属性name,虽然在stu对象中我们并没有明确的添加属性name,但是
stu的__proto__属性指向的原型中有name属性,所以这个地方可以访问到属性name
就值。
注意:这个时候不能通过stu对象删除name属性,因为只能删除在stu中删除的对象。
*/
alert(stu.name); // 张三 var stu1 = new students();
alert(stu1.name); // 张三 都是从原型中找到的,所以一样。 alert(stu.name === stu1.name); // true // 由于不能修改原型中的值,则这种方法就直接在stu中添加了一个新的属性name,然后在stu中无法再访问到
//原型中的属性。
stu.name = "李四";
alert(stu.name); //李四
// 由于stu1中没有name属性,则对stu1来说仍然是访问的原型中的属性。
alert(stu1.name); // 张三
</script>

三. 与原型有关的几个方法
**1. prototype属性**

prototype 存在于构造函数中 (其实任意函数中都有,只是不是构造函数的时候prototype我们不关注而已) ,他指向了这个构造函数的原型对象。

**2.constructor属性**

constructor属性存在于原型对象中,他指向了构造函数

如下面代码:

<script type="text/javascript">
function students () {
}
alert(students.prototype.constructor === students); // true
</script> 

我们根据需要,可以students.prototype 属性指定新的对象,来作为students的原型对象。但是这个时候有个问题,新的对象的constructor属性则不再指向students构造函数了。

**3.__proto__ 属性(注意:左右各是2个下划线)**

用构造方法创建一个新的对象之后,这个对象中默认会有一个属性__proto__, 这个属性就指向了构造方法的原型对象。

四. class(类)

 1 class Point {
2 constructor() {
3 // ...
4 }
5 toString() {
6 return '类似于够赞函数中的原型链,访问到这个原型身上的方法'
7 }
8 toValue() {
9 // ...
10 }
11 }
12
13
14 // 等同于
15 // Point.prototype = {
16 //toString(){},
17 //toValue(){}
18 //};
19
20 // 所以说
21 const p1 = new Point()
22 console.log(p1.toString()) //类似于够赞函数中的原型链,访问到这个原型身上的方法

 实例属性和静态属性(实例方法和静态方法)      

  这里我是进入了一个误区,但是通过打印发现

  拿下面的例子举例:我错误的认为 P1.info 是有值的,虽然构造函数身上追加了一个属性 info,显而易见,这是原型对象的 constructor 身上的属性,并不是原型对象身上的属性

,因为 原型对象的 constructor指向构造函数本身,这个info是构造函数身上的方法,而通过new出来的实例对象 P1.info 其实是通过原型链的形式访问原型对象身上的info属性,所以说访问的是 undefined,这里的 constructor属性和 P1 的 info属性都属于原型对象身上的属性,他俩是平级关系

  只要是通过new出来的实例能访问到的方法(属性),叫做实例方法,静态方法只存在构造函数本身

  实例属性:通过new出来的实例访问到的属性叫做实例属性

  静态属性:在构造函数中构造函数添加的属性 或者说 在class内部通过static 修饰的属性叫做静态属性

 1 function Person(name, age) {
2 this.name = name;
3 this.age = age;
4 }
5
  Person.show = function() { //静态方法
    console.log('这是静态方法')
  }
6 Person.info = '哈哈' //静态属性
  Person.prototype.say = function() { //这是实例方法,挂载到的是构造函数的原型对象身上,P1可以访问到
    console.log("这是实例方法,挂载到的是构造函数的原型对象身上,P1可以访问到")
  }
7 const P1 = new Person("范顺", 18);
8 console.log(P1.name) //通过new出来的实例访问到的属性叫做实例属性
9 console.log(P1.age)
10
11 console.log(P1.info) // undefined
12 console.log(Person.info) //静态属性
  P1.say() //这是实例方法,挂载到的是构造函数的原型对象身上,P1可以访问到


13
14
15 class Anmin {
16 constructor(name, age) {
17 this.name = name;
18 this.age = age;
19 }
20
21 // 在class内部通过static 修饰的属性叫做静态属性,只能被构造函数名或者类名读取,new出来的对象读不到
22 static info = '哈哈'
   say() {
    console.log('实例方法')
  }
  static show() {
    console.log('静态方法')
  }

23 }
24
25 const A1 = new Anmin('大黄', 9)
26
27 console.log(A1.name) //实例属性
28 console.log(A1.age)
29
30 console.log(A1.info) // undefined
31 console.log(Anmin.info) //静态属性
  console.log(A1.say()) //实例方法 say

class类的extends继承 

  继承父类的属性和方法

 1 class Father {
2 constructor(name, age) {
3 this.name = name
4 this.age = age
5 }
6 }
7 // 子类
8 class Person extends Father {
9 constructor(name, age, yellow) { //yellow 是子类定义的属性
10 super(name, age, yellow)
11 this.yellow = yellow
12 }
13 }
14
15 const P1 = new Person("范顺", 18, "红色")
16 console.log(P1)
17
18 // 子类
19 // class Anmainl {
20 // }
21
22 // const A1 = new Anmainl('二哈', 9)
23 // console.log(A1)

class(类)和构造函数(原型对象)的更多相关文章

  1. JavaScript 类、构造函数、原型

    类.构造函数.原型  :本质均为函数 利用的原理是:词法作用域,调用对象及作用域链  闭包  属性查找方式    设计和new运算符一起使用的函数叫做构造函数. 构造函数的工作:初始化一个新创建的对象 ...

  2. [转]JavaScript构造函数及原型对象

    JavaScript中没有类的概念,所以其在对象创建方面与面向对象语言有所不同. JS中对象可以定义为”无序属性的集合”.其属性可以包含基本值,对象以及函数.对象实质上就是一组没有特定顺序的值,对象中 ...

  3. 还在问什么是JavaScript构造函数、实例、原型对象以及原型链?看完这篇你就懂

    1概述 ES6, 全称 ECMAScript 6.0 ,2015.06 发版.在ES6之前,对象不是基于类创建的,而是用一种称为构造函数的特殊函数来定义对象和它们的特征. 2构造函数 构造函数是一种特 ...

  4. JS核心系列:原型对象

    在JS中,每当创建一个函数对象f1 时,该对象中都会内置一些属性,其中包括prototype和proto, prototype即原型对象. 每一个构造函数都有一个与之相关联的对象,该对象称之为原型对象 ...

  5. [js高手之路]使用原型对象(prototype)需要注意的地方

    我们先来一个简单的构造函数+原型对象的小程序 function CreateObj( uName, uAge ) { this.userName = uName; this.userAge = uAg ...

  6. javaScript系列 [03]-javaScript原型对象

    [03]-javaScript原型对象 引用: javaScript是一门基于原型的语言,它允许对象通过原型链引用另一个对象来构建对象中的复杂性,JavaScript使用原型链这种机制来实现动态代理. ...

  7. JS原型对象的问题

    原型模式最大的问题是由其共享的本性所导致的.我们知道,原型中所有的成员是被很多实例共享的,这种共享对于函数非常合适.对于那些包含基本值的属性倒也说得过去,毕竟可以通过在实例上添加一个同名的属性来隐藏原 ...

  8. 构造函数原型constructor

    对象原型(__proto__)和构造函数原型对象(prototype)里面都有一个属性constructor,constructor我们称为构造函数,因为它指向的是构造函数本身. constructo ...

  9. javascript面向对象系列第一篇——构造函数和原型对象

    × 目录 [1]构造函数 [2]原型对象 [3]总结 前面的话 一般地,javascript使用构造函数和原型对象来进行面向对象编程,它们的表现与其他面向对象编程语言中的类相似又不同.本文将详细介绍如 ...

  10. js深入理解构造函数和原型对象

    1.在典型的oop的语言中,如java,都存在类的概念,类就是对象的模板,对象就是类的实例.但在js中不存在类的概念,js不是基于类,而是通过构造函数(constructor)和原型链(propoty ...

随机推荐

  1. centos7中Firefox安装Flash插件

    第一步:先下载好Flash插件安装包,可以到Adobe官网下载.因为是linux 64位系统,所以要下个匹配的,我下载的是flash_player_npapi_linux.x86_64.tar.gz, ...

  2. 前端复习之JavaScript(ECMAScript5)

    啦啦啦啦啦啦啦啦绿绿绿绿绿绿 1 1.JavaScript: 2 前段三大语言:HTML CSS js 3 HTML:专门编写网页内容的语言 4 CSS:专门编写网页样式的语言 5 js:专门编写网页 ...

  3. 修改百分浏览器(centbrowser)、谷歌和火狐浏览器默认字体的方法

    1,百分浏览器(centbrowser) 在浏览器的安装位置D:\Program Files\Cent Browser\User Data编辑文件custome.css,如果没有此文件可新建一个,内容 ...

  4. Spring源码分析之getBean

    一.前言 spring作为JAVAEE最核心的框架,是每一个java开发者所必须掌握的,非常重要,本篇从一个简单例子入手,由浅入深的分析spring创建bean的全过程,目标在于彻底搞懂spring原 ...

  5. Java-02对象传递和返回

    Java-02对象传递和返回 当你在"传递"一个对象的时候,你实际上是在传递它的引用 1引用 1.1传递引用 当你将一个引用传给方法后,该引用指向的仍然是原来的对象: /** * ...

  6. superset连接mysql数据

    目前superset的官网没给出windows的安装教程,但是实际操作是可以的,网上有很多教程,再次就不赘述! 本篇随笔是介绍superset如何连接mysql数据源,本人踩坑踩了一整天.=_= ~~ ...

  7. C++/Qt网络通讯模块设计与实现(四)

    在C++/Qt网络通讯模块设计与实现(三)中提到了一个概念,即接受者所依附的线程:关注我微信公众号的技术朋友留言对该概念还是不解,这节就单独讲述这个概念的理论与实际应用,这种应用无处不在,因为与Qt的 ...

  8. Python Web开发初试,基于Flask

    目录 关于web框架 Python flask使用 关于web框架 仅仅对于应用层的coder而言,web框架的使用其实就是写路由,分发路由,写输出.当然如果要安全,要测试,要写优秀的接口,那需要继续 ...

  9. 【微信网页授权】SpringBoot+uniapp实现网页授权获取用户基本信息

    前言 缘由 起因于本狗上一个项目本打算采用微信公众号网页授权登录做用户鉴权,但最终因公众号是未认证的订阅号,无权限获取用户信息,所以改变思路,采用登录注册方式实现用户区分.但在开发中,学习了微信网页授 ...

  10. 很强,我终于找到绘制E-R图的正确姿势

    前言 不知道大家是不是和我一样,为了追求速度,开发时一般都是直接建表就干,哪管什么E-R图.直到xxx项目找上你,某某客户要E-R图,提供一下吧.这时候就很烦,从头绘制E-R图成本真的很高,今天我就遇 ...