Comments (11)
konw that,i will learn it when i have time
from blog.
主要伙伴@Hazlank是发了文章。然后跑过去看了。发现有些不明白就研究了一下。我只看了第一部分。第二部分没看。 所以只说第一部分的。感觉他写的有些鸡掰乱乱的,我自己改了一些排版。
from blog.
@Nbsaw prototype是function才有的属性
from blog.
所以看他的文章。先看第一个例子。
// 定义 SuperClass
function SuperClass(){
this.val = true
}
SuperClass.prototype.getVal = function(){
return this.val
}
SuperClass.prototype.o={
a:1
}
// 定义 SubClass
// 注意看这里把值设置成了false
function SubClass(){
this.val = false
}
// 注意这里。重新把构造器的引用变回原来的SubClass
SubClass.prototype = new SuperClass();
SubClass.prototype.constructor = SubClass;
var sub = new SubClass();
sub.o.a = 2;
console.log(sub.getVal())
// 创建其他的SubClass实例
console.log(new SubClass().o.a) //2
类的原型对象的作用就是为类的原型添加共有方法。当子类的原型对象指向实例化一个父类的时候,再去实例化这个子类的时候,实例化后的对象里的__proto__就是我们父类的prototype对象,所以就能够访问到父类原型对象的方法和构造属性了。
但是有个缺点,因为prototype是指向对象,对象和基本值不一样,是引用,所以我们更改其中的属性也就是相当于更改父类的属性,就会相互影响。
当然也可以通过父类的原型对象for-in循环复制到子类里,只要加上hasownproperty
的判断就好啦。
第一个方案不好主要是引用的问题。
from blog.
第一个列子设成false只是想为了表明。构造函数的属性只会在当前作用域的构造函数的实例中创建,单独的。
from blog.
看第二个例子。仔细看这里没有用到prototype了,而是用了call。
// 定义 SuperClass
function SuperClass(){
this.val = true
this.o={
a:1
}
}
// 定义 SubClass
function SubClass(){
SuperClass.call(this)
}
var sub1 = new SubClass()
console.log(sub1.val)
// 修改o
sub1.o.a=2
var sub2 = new SubClass();
console.log(sub2.o.a) //1
当我们实例化子类的时候,执行一遍父类的函数,利用call函数更改为子类的作用域,那么在this
添加属性的时候就会对子类的实例化对象添加属性了,这样创建的实例就会有单独拥有一份属性了,而不会共用,但是这就违背了代码复用的原则。
考虑下面这个
// 定义 animal
function animal(){
this.val = true
this.o={
a:1
}
}
animal.move = function(){console.log('move')}
// 定义 doge
function doge(){
animal.call(this)
}
如果你实例化doge
并调用move
方法你会发现调用不了,因为这个move
无法被继承。所以你可能改成这样子。
// 定义 animal
function animal(){
this.val = true
this.o={
a:1
}
this.move = function(){ console.log('move') }
}
// 定义 doge
function doge(){
animal.call(this)
}
然后你再尝试调用。你会发现这是可以的。但是这不好。这会让这个构造函数变的非常庞大如果有很多方法属性的话。更加糟糕的是,如果你要创建很多个相同的实例。那么每次会建很多次move
方法,这无疑很浪费性能。
from blog.
所以有第三种构造方法。组合构造
// 定义
SupClass = function(t){ this.t = t ; console.log('invoke'); }
SupClass.prototype.s = 's'
// 复用父类构造器
function SubClass(type){
SupClass.call(this,type)
}
SubClass.prototype = new SupClass()
// 这样写相当于这样。让prototype接盘了SubClass的实例。
// SubClass.prototype = SupClass.__proto__
// 这样写不会破坏SubClass。但是再下次实例化SubClass的时候会多出来不必要的东西
//(具体看输出结果的__proto__里面多出来的部分)
var obj = new SubClass('t');
console.log(obj)
// 因为这么做相当于
// obj.__proto__ = SubClass.prototype = new SupClass()
// 所以会多出一个实例在__proto__里面
// 一个是实例化prototype的本身的对象。一个是在原型里边的new SupClass()
这样就能共用方法和享有自己的副本了,但是还是有点瑕疵,为什么呢?因为构造函数被调用了两次,你可以看到控制台会在初始化的时候输出了两次invoke
。在初始化的时候会实例化一次构造器。并且在SubClass被实例化的时候又执行了一次。这无疑很多余。如果父构造器是一个比较复杂时间长的操作。这无疑加了不必要的创建时间。
from blog.
那么有第四种方法。
function inheritObject(o){
function F(){}
F.prototype = o;
return new F();
}
// 定义
SupClass = function(t){ this.t = t; console.log('invoke'); }
SupClass.prototype.s = 's'
// 复用父类构造器
function SubClass(type){
SupClass.call(this,type)
}
// 注意继承要提前写在前面。不然会覆盖掉掉子类的prototype
SubClass.prototype = inheritObject(SupClass.prototype);
SubClass.prototype.x = 'x'
SubClass.prototype.constructor = SubClass
new SubClass('t')
这个做法比上面那个好一点。不会多出来。更纯洁,开销更小。因为它只会在实例化SubClass
的时候被执行。避免了不必要的创建。这主要是因为使用了f
的空的构造器。
from blog.
书上还有其它几种方式,但我觉得没必要。
from blog.
@Hazlank TypeScript, Blade大法好
from blog.
@Nbsaw i konw that,i will learn it when i have time
from blog.
Related Issues (20)
- Explore the world of IOS / OSX developers HOT 1
- Ssh Passwordless Login
- CircleCi direct deploy app to server by ssh
- The high-quality TypeScript Declaration File.
- 把博客迁移到 Next.js HOT 3
- 98 HOT 1
- Mobx + useContext + ts = !!!! HOT 5
- 直接在微信内查看pdf文件的方法
- bilibili 出黑暗模式了 !!! HOT 2
- 弹窗设计思考
- circleci + jest + codecov 实现代码覆盖率统计
- SWR 不完全指南
- 理解 React Suspense
- 在Flutter里面使用Debounce函数
- Flutter 给IOS数字键盘加上完成按钮
- Flutter 开发体验汇总
- Typescript 动态枚举类型 (或者叫做限定类型) HOT 4
- Flutter 限制TextField 只允许输入小数
- 依赖反转原则
- Linux Tools Quick Tutorial Basic part
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from blog.