Web前端之路让前端飞

读zepto核心源码学习JS笔记(4)--内部方法

2017-06-13  本文已影响32人  一二三kkxx

根据第一篇整体框架,可以知道$()方法返回的Z函数的实例化;而Z的原型又指向$.fn;所以经过$()处理过的对象,都可以使用$.fn中的方法;
这一篇就记录一下读$.fn的笔记;

zepto.Z.prototype = Z.prototype = $.fn

一 内部函数

1. zepto.match

  //判断一个元素是否匹配给定的选择器
zepto.matches = function(element, selector) {
    //如果selector,element没值或者element是普通节点
    if (!selector || !element || element.nodeType !== 1) return false
    var matchesSelector = element.matches || element.webkitMatchesSelector ||
                          element.mozMatchesSelector || element.oMatchesSelector ||
                          element.matchesSelector
    if (matchesSelector) return matchesSelector.call(element, selector)
    // fall back to performing a selector:
    var match, parent = element.parentNode, temp = !parent
    if (temp) (parent = tempParent).appendChild(element)
    match = ~zepto.qsa(parent, selector).indexOf(element)
    temp && tempParent.removeChild(element)
    return match
 }
QQ截图20170610142612.png QQ截图20170610171446.png

二 $.fn

constructor

constructor: zepto.Z,

var person = function(name){
this.name = name;
}
var siva = new Person('Siva');
siva .__proto__ == person.prototype //true
person.prototype.constructor == person //true

由于zepto.Z.prototype = $.fn ;因此$.fn的构造函数即为zepto.Z

forEach

forEach: emptyArray.forEach,

reduce,push,sort,splice,indexOf

reduce: emptyArray.reduce,
push: emptyArray.push,
sort: emptyArray.sort,
splice: emptyArray.splice,
indexOf: emptyArray.indexOf,

get

get: function(idx){
//如果不传参,将Z对象转为数组, slice.call()在第三篇已经提到过;数组自有的slice;
//如果传参小于0,就将传的参数转换为idx加上传入对象的长度;即为倒数返回;
//例如传入的值为-1;则选取最后一个元素
  return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length]
},

在分析这句话之前,我们先看看get的用法;

QQ截图20170610142612.png QQ截图20170610142642.png

toArray

//将Z对象集合转换成数组
toArray: function(){ return this.get() },

concat

concat: function(){
  var i, value, args = []
  for (i = 0; i < arguments.length; i++) {
    value = arguments[i]
    //如果其中传入的参数为Z对象,则将其转为数组;并将值传给arg
    args[i] = zepto.isZ(value) ? value.toArray() : value
  }
  //apply方法将this强制绑定到调用concat的对象身上
  //如果调用concat的是Z对象,则将其转换成数组
  return concat.apply(zepto.isZ(this) ? this.toArray() : this, args)
},

slice

slice: function(){
//同上,将this强制绑定到调用的对象身上;
  return $(slice.apply(this, arguments))
},

ready

ready: function(callback){
//判断dom是否ready,如果已经ready,直接执行函数
  if (readyRE.test(document.readyState) && document.body) callback($)
  //否则注册监听器;
  else document.addEventListener('DOMContentLoaded', function(){ callback($) }, false)
  return this
},

size

size: function() {
  return this.length
},

each

each: function(callback){
  emptyArray.every.call(this, function(el, idx){
    return callback.call(el, idx, el) !== false
  })
  //可以使用链式操作
  return this
},

eq

eq: function(idx){
  return idx === -1 ? this.slice(idx) : this.slice(idx, + idx + 1)
},

first

first: function(){
  var el = this[0]
  return el && !isObject(el) ? el : $(el)
},

last

last: function(){
  var el = this[this.length - 1]
  return el && !isObject(el) ? el : $(el)
},

add

add: function(selector,context){
  return $(uniq(this.concat($(selector,context))))
},
uniq = function(array){ 
    return filter.call(array, 
    function(item, idx){ return array.indexOf(item) == idx })
}

map

map: function(fn){
  return $($.map(this, function(el, i){ return fn.call(el, i, el) }))
},

remove

remove: function(){
  return this.each(function(){
    if (this.parentNode != null)
      this.parentNode.removeChild(this)
  })
},

is

is: function(selector){
  return this.length > 0 && zepto.matches(this[0], selector)
},

not

not: function(selector){
  var nodes=[]
  //当selector为函数时,但是safari下的typeof odeList也是function,
  //所以这里需要再加一个判断selector.call !== undefined
  if (isFunction(selector) && selector.call !== undefined)
    this.each(function(idx){
    //当selector.call(this,idx)返回结果为false,记录;
      if (!selector.call(this,idx)) nodes.push(this)
    })
  else {
  //当selector为字符串的时候,筛选满足selector的记录;
    var excludes = typeof selector == 'string' ? this.filter(selector) :
    //当selector为类数组,将其变为数组,否则,执行$()
      (likeArray(selector) && isFunction(selector.item)) ? slice.call(selector) : $(selector)
    this.forEach(function(el){
    //筛选出不在excludes中的数据
      if (excludes.indexOf(el) < 0) nodes.push(el)
    })
  }
  //以上得到的是数组,将其转换成zepto对象;
  return $(nodes)
},
上一篇 下一篇

猜你喜欢

热点阅读