问: 谈一谈原型和构造函数在实际应用中的使用?
答: 原型和构造函数在jquery和zpeto中大量的被使用。
zepto的大概的流程是这样的:
//创建一个自执行函数,避免全局变量被污染
(function(window) {
// 声明一个zepto对象
var zepto = {};
function Z(dom, selector) {
var i, len = dom ? dom.length : 0
for(i=0;i<len;i++) {
this[i] = dom[len];
}
this.length = len;
this.selector = selector || ''
}
//Z方法new了一个Z的实例,说明Z是一个构造函数
zepto.Z = function(dom, selector) {
return new Z(dom, selector)
}
//init 函数将selector选中的类数组变成数组, 然后执行Z方法
zepto.init = function (selector) {
var slice = Array.prototype.slice;
var dom = slice.call(document.querySelector(selector));
return zepto.Z(dom, selector);
}
//$ 返回zepto初始化的方法
var $ = function(selector) {
return zepto.init(selector)
}
//给window一个$
window.$ = $;
$.fn = {
css: function(key, val) {
console.log(val)
},
html: function(val) {
console.log(val)
}
}
Z.prototype = $.fn
})(window)
jquery中的使用大致是这样的:
(function(window) {
//初始化$
var jQuery = function(selector) {
return new jQuery.fn.init(selector);
}
//定义fn方法
jQuery.fn = {
css: function(key, val) {
alert('css')
},
html: function(val) {
return 'html'
}
}
var init = jQuery.fn.init = function(selector) {
var slice = Array.prototype.slice;
var dom = document.querySelectorAll(selector);
var i, len = dom ? dom.length : 0;
for (i=0;i<len;i++) {
this[i] = dom[i]
}
this.length = len;
this.selector = selector;
}
//把fn方法挂载到init的prototype上
console.log(jQuery.fn)
init.prototype = jQuery.fn
//创建$方法
window.$ = jQuery;
})(window)
问题: 谈一谈jquery的插件机制(讲讲原型的扩展?)
答: jquery中, 是通过$.fn.方法名来扩展插件的。这样写的好处有两个:
向全局只暴露一个变量$,而没有构造函数Z(jquery.init).
方便统一管理
代码如下:
init.prototype = jQuery.fn
1
简单的实例:
<script type="text/javascript" src="./jquery-3.2.1.js"></script>
<script type="text/javascript">
// 插件扩展
$.fn.getNodeName = function () {
// this
alert(this[0].nodeName)
}
</script>
<script type="text/javascript">
// 验证
var $p = $('p')
$p.getNodeName()
var $div1 = $('#div1')
$div1.getNodeName()
</script>
1、原型的使用方法
(1)利用对象的动态特性给原型对象添加成员(属性、方法)
(2)直接替换原型对象:对象.prototype里面的prototype其实就是对象的一个属性,所以是可以修改替换的。如果使用过这种方式使用原型,那么会出现如下问题
<1>在替换原型之前创建的对象的原型 和 在替换原型对象之后创建的对象的原型 不是同一个
Person.prototype = {
msg:"你猜我在干啥"
};
function Person(name,age,gender){
this.name = name;
this.age = age ;
this.gender = gender;
}
Person.prototype.sayHello = function(){
console.log("你好");
};
var p = new Person("哈哈哈",19,"male");
p.sayHello();
//替换了原型对象
Person.prototype = { //prototype其实就是Person对象的一个属性
msg:"你猜我在干啥"
};
var p1 = new Person("12",12,"male");
console.log(p1.msg);
p1.sayHello(); //p1不能调用sayHello()
p.sayHello(); //p能调用sayHello()
为什么p1不能调用sayHello()而p2能?
替换原型对象之前:
替换原型对象之后: