18. class
Class
基本用法
class n {
constructor(x,y) {
this.x = x;
this.y = y;
console.log(x,y)
}
proint() {
console.log(' this is proint ')
}
}
var newObject = new n(1,2);
// c {x: 1, y: 2}
newObject.proint();
// this is proint
现在不用像以前.
function o(x,y) {
this.x = x;
this.y = y;
console.log(x,y)
}
o.prototype.proint = function() {
console.log(' this is proint ');
};
var oldObject = new o(1,2); //1,2
oldObject.proint() //this is proint
书中说这是语法糖.
也就是说。本质上依旧使用的是
ES5 版本的创建对象.
Class 不过一种简化的写法.
不过需要验证一下。 接下来的例子都会同时有两个版本.
n === n.prototype.constructor //true
o === o.prototype.constructor
newObject.constructor === n.prototype.constructor //true
oldObject.constructor === o.prototype.constructor //true
也就是这样.
为了说明他是语法糖.
Object.assign(n.prototype,{
mytest:function() { console.log('mytest') }
});
n.mytest() //mytest
n.prototype.proint //proint() { console.log(' this is proint ') }
constructor
你不写那么 javascript 就会为你自动创建一个空的
constructor() {}
new n() 就是调用 constructor 返回一个实例.
所以你可以改变返回的实例.
class foo {
constructor() {
return { y : 1 };
}
}
new foo() // { y : 1 }
类的实例对象
基本和ES5原型链基本一样.
this , prototype
以及
类的所有实例共享一个原型对象
完全是ES5的老内容.
不存在变量提升
我一直认为变量提升这种东西.
是你写代码不规范导致的.
不存在也就不存在吧.
Class的表达式
几种写法.
let n = class c { } //只有在class 内部调用才能调用C
let n1 = class { }
let n2 = new class { } //自执行相当于马上实例化.
私有方法
书中提到了3种方式.
- 前面加 **_** 下划线
- 将私有方法移出模块
- 用Symbol
前两种我表示都太垃圾..
第三种还有些意思
const bar = Symbol('bar');
const snaf = Symbol('snaf');export default class myClass{
// 公有方法
foo(baz) {
thisbar;
}// 私有方法
bar {
return this[snaf] = baz;
}// ...
};
这样确实可以私有。
百度了一波。 发现大部分都是使用 Symbol
例子中 bar 依然暴露在外.
没办法彻底的私有. 因为 Symbol 你如何防止随意的使用呢?
这样反而不如。 function 来的ok
function() {
var a1 = function() {};
return {
a : function() {
return a1();
}
}
}
继承
基本用法
class c1n extends n {}
基本的继承就是这样。 啥都不写。 完全照搬父类方法.
继承父类的一切。 this & prototype
你也可以自己写点儿啥.
具体的跟 ES5 并没有什么区别
需要注意的点在于 super,这个关键字.
它在 构造函数(constructor) 中,就是直接调用父类的构造函数.
它在普通的方法中,就是想到父类的this
class c1n extends n {
constructor(x,y,z) { super(x,y); this.z = z }
print() {
super.proint();
console.log('child print')
}
}
var o = new c1n(1,2,3);
o.print();
// this is proint
// child print
不调用父类的构造函数是无法创建自己的this
所以 super 是必须在构造函数中调用的。
当然如果你忘记了。 浏览器会自动为你调用。
前提是你参数没有问题.
类的prototype属性和__proto__属性
class c1n extends n { };
c1n.__proto__ === n;
c1n.prototype.__proto__ === n.prototype;
这种继承你完全可以自己模拟
Object.setPrototypeOf(c1n.prototype, n.prototype);
c1n.__proto__ = n;
就可以继承了.
Object.getPrototypeOf(c1n) === n
这样也可以获取父类.
super 关键字
super.
上面说过。 首先需要再 构造函数调用 super,调用父类的构造函数。
然后 super 会转变模式.
super 会指向父类的原型对象. 可以调用父类的方法.
super 引用当前子类的引用(this)
class a1 {
constructor(x,y) {
this.x = x;
this.y = y;
}
p() { console.log(this.x,this.y); }
}
class a2 extends a1 {
constructor(x,y) {
super(x,y);
this.x = 33;
}
p1() { super.p(); }
}
var o = new a2()
o.p1(); //33 undefined
所以 this.y 是 undefined.
Extends 的继承目标
上面代码的A,只要是一个有prototype属性的函数,就能被B继承。由于函数都有prototype属性(除了Function.prototype函数),因此A可以是任意函数。
也就是说
只要你有 prototype 属性. 且是一个函数,那就可以被继承.
书中讲了3个特殊情况.
继承
Object相当于Object 的一个复制class a {}
这种情况下,A作为一个基类(即不存在任何继承),就是一个普通函数,所以直接继承Funciton.prototype。但是,A调用后返回一个空对象(即Object实例),所以A.prototype.__proto__指向构造函数(Object)的prototype属性。
class a extends null
class C extends null {
constructor() { return Object.create(null); }
}
3.原生构造函数的继承
ES6 以前你并不能继承一些原生的对象.
Boolean()
Number()
String()
Array()
Date()
Function()
RegExp()
Error()
Object()
你并不能继承,去模拟它。
因为你不能继承到对象的构造函数 constructor.
但是 extends 可以
所以你可以完全继承一个 Array 来改造他.
class nArray extends Array {
constructor(...args) {
super(...args); //调用构造函数.
}
push(obj) {
//可以开始改造.
}
}
就是这样.
4. Class的取值函数(getter)和存值函数(setter)
可以有 get set. 虽然ES5 也有
class testClass {
get p() { console.log('b') }
set p(value) { console.log('a') }
}
5. Class的Generator方法
class testClass {
* [Symbol.iterator]() { }
}
6. Class的静态方法
class Foo {
static classMethod() {
return 'hello';
}
}
Foo.classMethod() // 'hello'
var foo = new Foo();
foo.classMethod()
// TypeError: foo.classMethod is not a function
就是静态类。 不用实例化就可以调用。
不过不能访问内部的东西。 可以用于某些设计模式.
ES6 不支持静态属性。 书中说 ES7 支持
8. new.target属性
new.target 能返回实例化的对象.
如果不是 new 实例化,就是 undefined.
function Person(name) {
if (new.target === Person) {
this.name = name;
} else {
throw new Error('必须使用new生成实例');
}
}
这就是一个例子。
必须是 Person 实例化.
利用这个特点,可以写出不能独立使用、必须继承后才能使用的类。
class Shape {
constructor() {
if (new.target === Shape) {
throw new Error('本类不能实例化');
}
}
}
class Rectangle extends Shape {
constructor(length, width) {
super();
// ...
}
}
var x = new Shape(); // 报错
var y = new Rectangle(3, 4); // 正确
就是这样.
大概了解了一下。 基本是以前就有的概念。当然也有一些没有的概念.
可以在实际中运用一下再来复盘一下.
18. class的更多相关文章
- CSharpGL(18)分别处理glDrawArrays()和glDrawElements()两种方式下的拾取(ColorCodedPicking)
CSharpGL(18)分别处理glDrawArrays()和glDrawElements()两种方式下的拾取(ColorCodedPicking) 我在(Modern OpenGL用Shader拾取 ...
- ABP(现代ASP.NET样板开发框架)系列之18、ABP应用层——权限验证
点这里进入ABP系列文章总目录 ABP(现代ASP.NET样板开发框架)系列之18.ABP应用层——权限验证 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(18)-权限管理系统-表数据
系列目录 这一节,我们插入数据来看看数据流,让各位同学,知道这个权限表交互是怎么一个流程,免得大家后天雾里来雾里去首先我再解释一些表,SysUser和SysRole表不用解释了. SysRoleSys ...
- C#开发微信门户及应用(18)-微信企业号的通讯录管理开发之成员管理
在上篇随笔<C#开发微信门户及应用(17)-微信企业号的通讯录管理开发之部门管理>介绍了通讯录的部门的相关操作管理,通讯录管理包括部门管理.成员管理.标签管理三个部分,本篇主要介绍成员的管 ...
- [MySQL Reference Manual] 18 复制
18 复制 18 复制 18.1 复制配置 18.1.1 基于Binary Log的数据库复制配置 18.1.2 配置基于Binary log的复制 18.1.2.1 设置复制master的配置 18 ...
- Hihocoder 太阁最新面经算法竞赛18
Hihocoder 太阁最新面经算法竞赛18 source: https://hihocoder.com/contest/hihointerview27/problems 题目1 : Big Plus ...
- grep-2.26 sed-4.2.2 awk-4.1.4 wget-1.18 pcregrep-8.39 pcre2grep-10.22 for windows 最新版本静态编译
-------------------------------------------------------------------------------------------- grep (G ...
- 《C#本质论》读书笔记(18)多线程处理
.NET Framework 4.0 看(本质论第3版) .NET Framework 4.5 看(本质论第4版) .NET 4.0为多线程引入了两组新API:TPL(Task Parallel Li ...
- Java随机生成18位身份证号
package com.ihome.data; import java.text.SimpleDateFormat; import java.util.Calendar; import java.ut ...
- tornado学习笔记18 _RequestDispatcher 请求分发器
根据Application的配置,主要负责将客户端的请求分发到具体的RequestHandler.这个类实现了HTTPMessageDelegate接口. 18.1 构造函数 定义: def __in ...
随机推荐
- [备查]使用 SPQuery 查询 "Person or Group" 字段
原文地址:http://www.stum.de/2008/02/06/querying-the-person-or-group-field-using-spquery/ Querying the “P ...
- npm更新到最新版本的方法
打开命令行工具 npm -v 查看是否是最新版本 如果不是 运行npm i npm g 升级 打开C:\Users\用户名用户目录找到node_modules 文件夹下的npm文件夹,复制一份 打开n ...
- 使用WebRTC搭建前端视频聊天室——入门篇
http://segmentfault.com/a/1190000000436544 什么是WebRTC? 众所周知,浏览器本身不支持相互之间直接建立信道进行通信,都是通过服务器进行中转.比如现在有两 ...
- 关于Android中的三级缓存
三级缓存的提出就是为了提升用户体验.当我们第一次打开应用获取图片时,先到网络去下载图片,然后依次存入内存缓存,磁盘缓存,当我们再一次需要用到刚才下载的这张图片时,就不需要再重复的到网络上去下载,直接可 ...
- IOS-小项目(饿了么 网络部分 简单实现)
在介绍小项目之前,在此说明一下此代码并非本人所写,我只是随笔的整理者. 在介绍之前先展现一下效果图. 看过效果图大家应该很熟悉了,就是饿了么的一个界面而已,值得注意的是,实现时并没有采用本地连接,而是 ...
- C#委托的介绍(delegate、Action、Func、predicate)
委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递.事件是一种特殊的委托. 1.委托的声明 (1). delegate delegate我们常用到的一种声明 Deleg ...
- IDEA 中scala 程序运行时的错误:报错 test is already defined as object test
解决办法:在 创建main文件夹和scala文件夹的时候,注意src与这两个文件夹不能同时设置为resources,否则就会产生报错,解决办法将src文件夹的resources取消,右键.
- Android 强制设置横屏或竖屏 设置全屏
(转自:http://blog.csdn.net/yuejingjiahong/article/details/6636981) 强制横屏: @Override protected void onRe ...
- ASP.NET MVC - 定制属于你自己的ViewEngine
http://blog.csdn.net/jackvs/article/details/7788743 ASP.NET MVC出来这么久了,心中却又很多的疑惑:为什么所有的View都要放在Views目 ...
- [LeetCode] Number of Islands 岛屿的数量
Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surro ...