如何准确判断一个变量是数组类型 写一个原型链继承的例子 描述new一个对象的过程 zepto(或其他框架)源码中如何使用原型链
构造函数
new一个构造函数,返回一个对象的过程
new的时候把参数传入也可不传 new函数执行时,创建一个空对象 this指向这个新对象this = {}
执行代码,即对this.name等开始顺序赋值 赋值完后,默认return this 赋值给f
,f.name
、f.age
、f.class
生效
function Foo ( name, age) {
this . name = name;
this . age = age;
this . class = 'class-1' ;
}
var f = new Foo ( 'zhangsan' , 20 ) ;
Tips
var obj = {}
其实是var obj = new Object()
的语法糖var arr = []
其实是var arr = new Array()
的语法糖var fn = funtion () {...}
其实是var fn = new Function()
的语法糖所有的引用类型(对象、数组、函数)都有构造函数 推荐使用前者的写法
原型
5条原型规则和示例
所有 的引用类型(数组、对象、函数),都具有对象 特性,即可自由扩展属性(null
除外)
var obj = { } ;
obj. a = 100 ;
var arr = [ ] ;
arr. a = 100 ;
var fn = function ( ) { } ;
fn. a = 100 ;
所有的引用类型 ,都有一个__proto__
属性(隐式原型属性),属性值是一个普通的对象
console. log ( obj. __proto__) ;
console. log ( arr. __proto__) ;
console. log ( fn. __proto__) ;
所有函数 ,都有一个prototype
属性(显式原型属性),属性值是一个普通的对象
Number、String、Boolean、Object 、Array 、Function 、Date、RegExp、Error(一定要大写)都是函数
console. log ( fn. prototype) ;
所有引用类型 ,__proto__
属性值指向(完全等===)他的构造函数的prototype
属性值
console. log ( obj. __proto__ === Object. prototype)
当试图得到一个对象的某个属性时,若果这个对象本身没有这个属性,那么在它的__proto__
(即它的构造函数的prototype
)中寻找
function Foo ( name, age) {
this . name = name;
}
Foo. prototype. alertName = function ( ) {
alert ( this . name) ;
}
var f = new Foo ( 'zhangsan' ) ;
f. printName = function ( ) {
console. log ( this . name) ;
}
f. printName ( ) ;
f. alertName ( ) ;
f本身没有alertName
的属性,所以会去f的隐式原型__proto__
中去寻找,f的隐式原型__proto__
即为其构造函数Foo的显式原型prototype
,Foo的显式原型已被扩展了alertName
的属性,所以可顺利执行 this永远指向对象本身,在执行f.alertName()
的时候会执行到第6行alert(this.name)
,但是这里的this还是f本身
原型链
f.toString()
-> f.__proto__
-> Foo.prototype
-> 无toString
属性 -> Foo.prototype
是一个对象 -> Foo.prototype.__proto__
-> Object.prototype
-> f.__proto__.__proto__
Object.prototype.__proto__ = null
function Foo ( name, age) {
this . name = name;
}
Foo. prototype. alertName = function ( ) {
alert ( this . name) ;
}
var f = new Foo ( 'zhangsan' ) ;
f. printName = function ( ) {
console. log ( this . name) ;
}
f. printName ( ) ;
f. alertName ( ) ;
f. toString ( ) ;
instanceof
判断引用类型 属于哪个构造函数 的方法 f instanceof Foo
判断逻辑:f
的__proto__
一层一层往上,能否对应到Foo.prototype
f instanceof Object
判断逻辑:f
的__proto__
一层一层往上,是否对应到Object.prototype
循环对象自身属性
从上述代码中可得f拥有三个属性:name、printName、alertName 但我们往往希望拿到对象本身定义的属性,而不要来自其原型的属性
var item;
for ( item in f) {
if ( f. hasOwnProperty ( item) ) {
console. log ( item)
}
}
题目解答
如何准确判断一个变量是数组类型
var arr = [ ]
arr instanceof Array
typeof arr
写一个原型链继承的例子
function Animal ( ) {
this . eat = function ( ) {
console. log ( 'animal eat' ) ;
}
}
function Dog ( ) {
this . bark = function ( ) {
console. log ( 'dog bark' ) ;
}
}
Dog. prototype = new Animal ( ) ;
var hashiqi = new Dog ( ) ;
hashiqi. eat ( ) ;
hashiqi. bark ( ) ;
function Elem ( id) {
this . elem = document. getElementById ( id) ;
}
Elem. prototype. html = function ( val) {
var elem = this . elem;
if ( val) {
elem. innerHTML = val;
return this ;
} else {
return elem. innerHTML
}
}
Elem. prototype. on = function ( type, fn) {
var elem = this . elem;
elem. addEventListener ( type, fn) ;
return this ;
}
var div1 = new Elem ( 'div1' ) ;
console. log ( div1. html ( ) ) ;
div1. html ( '<p>hello world</p>' ) . on ( 'click' , function ( ) {
alert ( 'clicked' ) ;
} ) . html ( '<p>javascript</p>' )
描述new一个对象的过程
创建一个空对象 this指向这个新对象 执行代码即对this赋值 返回this
zepto(或其他框架)源码中如何使用原型链
阅读源码是最高效提高技能的方式 但不能“埋头苦钻”,有技巧在其中,搜索别人的阅读体会 慕课网搜索“zepto设计和源码分析” 在面试时说出读过源码并分享心得体会十分加分 jQuery也可 Vue、React不建议现在读