You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
functionPerson(){}Person.prototype.name="Nicholas";Person.prototype.age=29;varperson1=newPerson();alert(person1.hasOwnProperty("name"));//falsealert("name"inperson1);//true//无论该属性存在于实例中还是存在于原型中。//同时使用 hasOwnProperty()方法和 in 操作符,//就可以确定该属性到底是存在于对象中,还是存在于原型中。functionhasPrototypeProperty(object,name){return!object.hasOwnProperty(name)&&(nameinobject);}
functionnewObject(){//创建一个空对象letobj=newObject();//获取构造函数letConstructor=[].shift.call(arguments);//链接到原型obj.__proto__=Constructor.prototype;//绑定this值//使用apply,将构造函数中的this指向新对象,//这样新对象就可以访问构造函数中的属性和方法letresult=Constructor.apply(obj,arguments);//返回新对象//如果返回值是一个对象就返回该对象,否则返回构造函数的一个实例对象returntypeofresult==="object" ? result : obj;}
"use strict";//_instanceof方法判断this实例是否是构造函数生成function_instanceof(left,right){if(right!=null&&typeofSymbol!=="undefined"&&right[Symbol.hasInstance]){returnright[Symbol.hasInstance](left);}else{returnleftinstanceofright;}}//`classCallCheck防止类的直接调用function_classCallCheck(instance,Constructor){if(!_instanceof(instance,Constructor)){thrownewTypeError("Cannot call a class as a function");}}//_defineProperty方法定义类中定义的属性function_defineProperty(obj,key,value){if(keyinobj){Object.defineProperty(obj,key,{value: value,enumerable: true,configurable: true,writable: true});}else{obj[key]=value;}returnobj;}//创建构造函数varParent=functionParent(a){_classCallCheck(this,Parent);_defineProperty(this,"filed2",2);_defineProperty(this,"func1",function(){});this.filed1=a;};
类的继承:类的继承是通过extends和super来实现的。
//ES6继承classChildextendsParent{constructor(name,age){super(name,age);}coding(){console.log("I can code JS");}}
babel转换:
//ES6继承//判断可能的返回值function_possibleConstructorReturn(self,call){if(call&&(_typeof(call)==="object"||typeofcall==="function")){returncall;}return_assertThisInitialized(self);}//判断this是否继承和super是否调用function_assertThisInitialized(self){if(self===void0){thrownewReferenceError("this hasn't been initialised -
super()hasn't been called");
}returnself;}//继承的主要实现方法function_inherits(subClass,superClass){if(typeofsuperClass!=="function"&&superClass!==null){thrownewTypeError("Super expression must either be null or a function");}subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor: {value: subClass,writable: true,configurable: true}});if(superClass)_setPrototypeOf(subClass,superClass);}//设置原型function_setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf||function_setPrototypeOf(o,p){o.__proto__=p;returno;};return_setPrototypeOf(o,p);}//父构造函数varParent=functionParent(a){_classCallCheck(this,Parent);_defineProperty(this,"filed2",2);_defineProperty(this,"func1",function(){});this.filed1=a;};//子构造函数varChild=function(_Parent){_inherits(Child,_Parent);functionChild(name,age){_classCallCheck(this,Child);return_possibleConstructorReturn(this,_getPrototypeOf(Child).call(this,name,age));}_createClass(Child,[{key: "coding",value: functioncoding(){console.log("I can code JS");}}]);returnChild;}(Parent);
1、理解原型设计模式以及
javascript
中的原型规则原型模式:使用构造函数的
prototype
属性来指定那些应该共用的属性和方法。javascript
语言中,除来undefined
,symbol
,其他类型都会被包装成对象来处理(Number、String、Boolean)
,来方便我们共享一些属性和方法。new
一个构造函数;{}
创建;Object
的一些方法;原型规则 :
in
操作符单独使用可以判断属性是否可以被对象访问,无论该属性存在实例中还是原型中;在使用for-in
循环时,返回的是所有能够通过对象访问的、可枚举的(enumerated)
属性,其中既包括存在于实例中的属性,也包括存在于原型中的属性。prototype
指向共享的对象,我们通过new
这个构造函数来获取这些共享的属性和方法;而每个对象都有一个__proto__
属性指向一个Object
。而new形成的实例,就是把__proto__
指向来构造函数的prototype
。prototype===
实例的__proto__
;String、Number、Boolean、Symbol、Undefined、Null
。Object
。2、instanceof的底层实现原理,手动实现一个instanceof
instanceof
是用来判断引用类型,也可以通过原型链实现继承关系的判断。instanceof
的实现实际上是调用JS
内部函数 [[HasInstance]] 来实现的。3、实现继承的几种方式以及他们的优缺点
继承是面向对象的编程中最重要的概念,在语言中都支持两种继承方式:接口继承和实现继承。接口继承只继承方法名,而实现继承则- 继承实际的方法。在Js中无法实现接口继承,只支持实现继承,也就是原型链继承。
原型链继承:利用原型让一个引用类型继承另一个引用类型的方法和属性。
缺点:构造函数原型上的属性在所有该构造函数构造的实例上是共享的,即属性没有私有化,原型上属性的改变会作用到所有的实例上。
借用构造函数继承:在构造子类构造函数时内部使用call或apply来调用父类的构造函数。
优缺点:实现了属性的私有化,但是子类无法访问父类原型上的属性。
组合继承:利用构造函数和原型链的方法,可以比较完美的实现继承。
寄生继承:即将
sub.prototype=new super改为sub.prototype=Object.creat(supper.prototype)
,避免了组合继承中构造函数调用了两次的弊端。4、至少说出一种开源项目(如
Node
)中应用原型继承的案例node
中继承通过util
中的inherites
方法来实现。接受两个参数,第一个参数是要继承的构造函数,第二个参数是父类的构造函数,通过子类的prototype
指向一个新对象,新对象是拷贝父类的prototype
,并修改constructor
指向子类自己。5、可以描述
new
一个对象的详细过程,手动实现一个new操作符new
一个对象的详细过程:__proto__
指向构造函数的prototype
;this
;6、理解
es6 class
构造以及继承的底层实现原理class的构造:
javascript
的底层离不开构造函数,可以说构造函数是js
语言的核心。而class
类是对构造函数的一种规范使用。创建一个类:
babel
转换:类的继承:类的继承是通过
extends
和super
来实现的。babel
转换:在理解
_inherits
函数之前我们需要明白:Function.__proto__===Function.prototype
;Function.prototype.__proto__.constructor===Object
;Function.__proto__.constructor===Function
;`_inherits``函数的核心就是
subClass.__proto__=superClass
;subClass.prototype__proto__=superClass.prototype
;superClass.prototype.constructor=subClass
;The text was updated successfully, but these errors were encountered: