日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

jquery内核学习(6)--扩展实现extend

發布時間:2025/7/14 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jquery内核学习(6)--扩展实现extend 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本篇繼續豐富我的jquery框架,利用extend來擴展!

擴展的優點

不必每次增加新的方法都直接往jQuery或者jQuery.fn追加.?

jQuery.fn.extend({fun1: function() {console.log('this is an extend function');} })

通過這樣的方法就能為jQuery擴展一個名叫fun1()的方法.然后能直接調用它

$('div').fun1(); //this is an extend function

extend()方法的基本思想就是把指定對象的方法都復制給jQuery或者jQuery.prototype對象!?

jQuery.extend = jQuery.fn.extend = function( obj ) {for ( var name in obj ) {this[ name ] = obj[ name ];}return this; }

?知識拓展

jQuery中的extend()方法遠比上面幾行代碼復雜,強大!下面是官網提供的API.

jQuery.extend( target, [ object1 ], [ objectN ] );//example var object1 = {apple: 0,banana: {weight: 52, price: 100},cherry: 97 }; var object2 = {banana: {price: 200},durian: 100 };
jQuery.extend( object1, object2 ); //result var object1 = {apple: 0,banana: {weight: 52, price: 100}, durian: 100,cherry: 97 }?

target:屬性合并后的集合.

object[1...n]:待合并的屬性,若target沒有則直接加入,否則重寫(覆蓋).

1.若有新屬性合并進來,則破壞了target原來的結構.

jQuery.extend( { }, target, [ object1 ], [ objectN ] ); //合并后的結果將輸入到{ }中.//example var defaults = { validate: false, limit: 5, name: "foo" }; var options = { validate: true, name: "bar" };var merge = jQuery.extend( { }, defaults, options );//result /* var defaults = { validate: false, limit: 5, name: "foo" }; var options = { validate: true, name: "bar" }; var merge = {"validate":true,"limit":5,"name":"bar"}; */?

2. 若extend()接受的參數是唯一的.則合并到jQuery的環境中去.

jQuery.extend( target );//test jQuery.extend({test: function() {console.log( 'I'm an example' );} })jQuery.test(); //I'm an example

帶選項的深度extend()方法

jQuery.extend( [ deep ], target, object1, [ objectN ] );

deep(boolean): 若取值true,將會遞歸的合并(深度copy).

其它的參數含義如上.

何為深度copy?

//example var object1 = {apple: 0,banana: {weight: 52, price: 100},cherry: 97 }; var object2 = {banana: {price: 200},durian: 100 };jQuery.extend( true, object1, object2 );//result /* var object1 = {apple: 0,banana: {weight: 52, price: 200},cherry: 97,durian: 100 } */

?深度copy:為每個子對象遞歸調用extend()方法!

源碼解析

jQuery.extend = jQuery.fn.extend = function() {/** options: 復制操作的對象及object[1...n]* name: object[1...n]里面的每項* src: 目標對象* copy: 復制的項目,也是遞歸copy的操作對象* copyIsArray: copy的對象是數組* clone: 需要遞歸copy的目標對象* */var options, name, src, copy, copyIsArray, clone,//復制操作的目標對象target = arguments[0] || {},i = 1,length = arguments.length,//是否進行深度copydeep = false;//若傳遞的第一個參數是boolean(false,true),則處理是否深度copyif ( typeof target === "boolean" ) {deep = target;//第二個參數變成copy的目標對象target = arguments[1] || {};//掠過boolean值i = 2;}// 若目標對象為字符串則置空對象targetif ( typeof target !== "object" && !jQuery.isFunction(target) ) {target = {};}//唯一參數的時候,目標對象是當前環境thisif ( length === i ) {target = this;--i;}//處理需要進行copy的對象for ( ; i < length; i++ ) {//只對非空對象進行處理if ( (options = arguments[ i ]) != null ) {for ( name in options ) {//相當于hash查找target中是否有name這一項,沒有則加入,有則重寫src = target[ name ];copy = options[ name ];//阻止死循環發生if ( target === copy ) {continue;}//若copy是一個對象或者是一個數組,則進行遞歸的copyif ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {if ( copyIsArray ) {copyIsArray = false;//相當于上面的target = {}; 定義進行遞歸copy的目標對象clone = src && jQuery.isArray(src) ? src : [];} else {clone = src && jQuery.isPlainObject(src) ? src : {};}//遞歸調用target[ name ] = jQuery.extend( deep, clone, copy );//其它情況則直接重寫!} else if ( copy !== undefined ) {target[ name ] = copy;}}}}//返回合并后的對象return target; };

發現的問題

源碼中有一點值得注意的:

// 若目標對象為字符串則置空對象target if ( typeof target !== "object" && !jQuery.isFunction(target) ) {target = {}; }?

其實不能只單純的理解為目標對象為字符串!分析源碼不難發現.這里的條件是:

target不是"object",并且target也不是"function "!怎么說呢?如下:

var object1 = {name: 'Poised-flw',age: 20 }//Number var test1 = jQuery.extend( 123, object1 ); //Object {name: "Poised-flw", age: 20} //String var test2 = jQuery.extend( 'Poised-flw', object1 ); //Object {name: "Poised-flw", age: 20} //Array var test3 = jQuery.extend( [ 1, 3, 4 ], object1 ); //Object {name: "Poised-flw", age: 20} //...more//以上的用法其實就相當于 var test = jQuery.extend( { }, object1 );

話說還有個更奇妙的地方.當typeof target是"function"的時候會產生什么樣的結果?

var object1 = {name: 'Poised-flw',age: 20,test: 'haha' }var fun = function() {console.log('I'm a function'); }var result = jQuery.extend( fun, object1 );/*something interesting*/ typeof result; //"function" result(); //'I'm a function' result['name']; //"" result['age']; //20 result.test; //"haha"

函數還能這么用,這玩意不多見...井底之蛙了...@^@

不過還有個問題呀...^_^

result.name; //"" 為什么不是"Poised-flw" result['name']; //"" 為什么不是"Poised-flw"

以下是解釋:

function.name

name屬性返回一個function的名字,當function是一個匿名函數的時候返回一個空串(Chrome & Opera & Firefox & Safari),IE不支持此屬性(undefined)!

//example 1 function doSomething() {console.log(doSomething.name); //expcept IE: "doSomething", but for IE: undefined }//example 2 var fun = function() {console.log(fun.name); //except IE: "", and for ie: undefined }

注意:name屬性是只讀屬性,并不允許修改!就像length屬性一樣.

//the name property var fun = function() {//... }//the same with length console.log(fun.name); //"" fun.name = "Poised-flw"; //"Poised-flw" console.log(fun.name); //""//the length property console.log( (function() {}).length ); //0 console.log( (function(a, b) {}).length ); //2//for firefox. function.length does not include the "rest parameter" /*About rest parameter:以...開始的參數,代表一個數組.范圍是從0到數組的長度function(a, b, ...Args) { //... } */ console.log( (function(a, ...Args) {}).length ); //1

//notice! arguments.length將返回實際傳入函數的參數個數
/*
* function f( a, b, c, d ) {
* console.log( f.length );
*  console.log( arguments.length );
* }
* f( 1, 2, 3 ); //4, 3
*/

到此自己的jquery框架也算具備可擴展性了!接下來就是豐富它!

轉載于:https://www.cnblogs.com/Poised-flw/archive/2013/04/24/3040630.html

總結

以上是生活随笔為你收集整理的jquery内核学习(6)--扩展实现extend的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。