jQuery系列:五个模块总结
Query插件,以备并希望在前端方面有所长进。请批评指正。
一,类型判断全解
JQuery判断类型扩展方法:$.type()
/*type: function( obj ) {
if ( obj == null ) {
return obj + "";
}
return typeof obj === "object" || typeof obj === "function" ?
class2type[ toString.call(obj) ] || "object" :
typeof obj;
}*/
$.type()
本质:就是运用{}.toString.call()或者(Object.prototype.toString.call())。
自己模仿写出来一个方法:
function getType(o) {
var _target;
return (
(_target = typeof (o)) == "object" ? Object.prototype.toString.call(o).slice(8, -1) : _target)
.toLowerCase();
}
getType
但这个方法只是判断继承Object复杂类型下的Date Array RegExp等typeof判断不出的子类型。
1,typeof 2,instanceof 3,constructor 4,{}.toString.call()或者(Object.prototype.toString.call())
Boolean Number String Function Array Date RegExp Object Error Null Undefined
//1,数据类型:5种简单基本类型:Undefined Boolean String Number Null 1种复杂类型Object
//2,但根据返回值得到的类型有6种,“undefined” “boolean” “string” “number” “function” “object”。注意将Null去掉,换成“function”。都以小写字母开头
//比如操作符操作字符串会返回上面6种,注意一点:将typeof null会返回“object”,注意返回object的表示这个值是对象(包括Array)或者null,
//1Array Date返回object 2Math 数字返回number 3字符串new返回object 直接定义返回object
var arr1 = [1, 2, 3];
var arr2 = new Array()
var dat = new Date();
var mat1 = Math.PI;
var mat2 = Math.random();
alert(typeof arr1);//object
alert(typeof arr2);//object
alert(typeof dat);//object
alert(typeof mat1);//number
alert(typeof mat2);//number alert(typeof [])//object
alert(typeof null);//object
//字符串有点特殊
var s1 = 'abc';
var s2 = new String('def');
alert(typeof s1);//string
alert(typeof s2);//object function fun() { }
alert(typeof fun);//function
//3,一般null==undefined返回true ,null===undefined 返回false
if (null == undefined) { alert(true) }//true
if (null === undefined) { alert(true) } else {
alert(false);
}
//4,Boolean 转换成false的的类型 “” 0和NaN null undefined
typeof
//instance
var a = "abc.";
var b = 1;
var c = [1, 2, 3];
var d = new Date();
var e = function () { alert(1); };
var f = function () { this.name = "2"; };
alert(c instanceof Array) //true
alert(d instanceof Date)
alert(f instanceof Function)//true
// alert(f instanceof function)// false
//instanceof 后面一定要是对象类型,注意大小写不能错
instanceof
function A() { }
alert(typeof A);//function
var a = new A();
alert(typeof a);//object //构造函数
//new 1创建实例 2将函数的原型赋值给这个实例 3执行这个函数 并且这个函数的上下文this就是这个实例
alert(a.constructor)// function A() { }
alert(a.constructor === A)//true ***************注意实例能直接调用对应原型中属性方法。比如a直接调用原型中的constructor
constructor
function A() { }
var a = new A();
alert({}.toString.call(a))//[object Object]
alert({}.toString.call(A))//[object Function]
alert(Object.prototype.toString.call([]))//[object Array]
alert({}.toString.call([]))//[object Array]
alert({}.toString.call(new Date()))//[Object Date]
{}.toString.call()或者(Object.prototype.toString.call())
/1typeof:判断除了Null的5个基本类型准确,但是想Date Array Regexp不准 2先知道类型,再判断是否是这个类型
//instaneceof,准确,但必须先知道类型,然后判断是否为这个类型
//constructor(得到构造函数
//跨iframe时候 instanceof 和constructor有问题,具体什么问题不清楚
//用jquery.type(),把null undefined 复杂类型和 除null和undefined外的4中基本类型都包含了。 核心代码{}.toString.call(obj) //[object ...]
二,创建对象全解
jQuery创建$(),这$()是个方法,里面renturn一个对象,new的时候,覆盖构造函数的对象。运用构造函数+寄生创建对象,核心理解原型链。
var jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context );
} jQuery.fn = jQuery.prototype = {
init: function( selector, context ) {
var match, elem, ret, doc; // Handle $(""), $(null), or $(undefined)
if ( !selector ) {
return this;
}
....... jQuery.fn.init.prototype = jQuery.fn;
$()对象创建
return new jQuery.fn.init( selector, context );为什么不直接返回new jQuery();应为new的时候,会调用jQuery....然后又new..死循环。
将jquery下的prototype下的init方法的原型=jquery下的prototype。意思:newjQuery.fn.init()对象具有 init方法的原型中的所有方法 的实例,就会具有jquery下的prototype下的所有方法,扩展jquery下的prototype下的方法。就等于扩展$()的方法。
创建对象的形式:说的3种,5种什么的,没什么意思的。其实看书之后总结是7种,不过没什么意思。核心还是构造函数+原型,知道之后其余的稍微看一下就会的。
原始:var obj={};或者var obj=new Object() ;obj.attr1=..,obj.attr2=..
工厂:function factory(par1,par2,...){var obj=new Object();obj.attr=par1..;return obj}
构造函数:function A(){} var a=new A();
构造函数+原型:function A(){} var a=new A(); A.prototype={attr1:..;fun1:...}
动态构造函数:function A(){this.attr1=..;this.attr2=..;if(typeof this.fun1!='function'){A.prototype.fun1=function(){....}}} var a=new A(); a.fun1();//函数内部没有的,我再在原型中创建。这个整体写法,将原型写到方法体内了。就相当我们c#的语言一样了,将类的所有的方法写到一个类中。
寄生构造函数:function A(){vat a=new ..;this.attr1=... return a;}//return的结果,覆盖构造函数new时候默认返回的实例。
稳妥构造函数:看高级编程之后,实在发现不出和工厂方法有什么区别。这都什么飞机?我简单认为就是工厂模式。核心为了“安全”,不使用this,不使用new。
三,引用问题
//在h5游戏开发中,经常会有这样的要求:复制出一个对象,但修改原来的对象,不会造成对复制出的对象造成影响。我们需要理解一些基本的东西。
//1在闭包内,尽量不适用同一个变量名,比如下面的a。因为作用域就近找变量。不会按照人眼看到的从上到下执行。
//2变量和函数的声明,放到最上面。因为js程序运行的时候自动会将声明提升到当前作用域的最顶端
var a = "global";
function b() {
console.log(a);//undefined 1先在当前上下文作用域内找a,就近原则!。当前作用于内不存在,就从上级作用域找...上级
var a = "local";//此时var a声明会提升到当前上下文(作用域最顶端)
console.log(a);//local
}
b(); var m = "global";
function n() {
var m;
console.log(m);//undefined
m = "local";
console.log(m);//local
}
n();
var k = "global";
function l() {
var k;
console.log(k);//undefined 找到当前作用域的k,就不会再往作用域链上继续找
console.log(k);//undefined
}
l();
var s = "global";
function t() {
console.log(s);//undefined 找到当前作用域的k,就不会再往作用域链上继续找
console.log(s);//undefined
}
t();
变量,函数声明的习惯。常出现的错误
四,扩展实质全解
jQuery.extend = jQuery.fn.extend = function() {
// copy reference to target object
var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy; // Handle a deep copy situation
if ( typeof target === "boolean" ) {
deep = target;
target = arguments[1] || {};
// skip the boolean and the target
i = 2;
} // Handle case when target is a string or something (possible in deep copy)
if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
target = {};
} // extend jQuery itself if only one argument is passed
if ( length === i ) {
target = this;
--i;
} for ( ; i < length; i++ ) {
// Only deal with non-null/undefined values
if ( (options = arguments[ i ]) != null ) {
// Extend the base object
for ( name in options ) {
src = target[ name ];
copy = options[ name ]; // Prevent never-ending loop
if ( target === copy ) {
continue;
} // Recurse if we're merging object literal values or arrays
if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) {
var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src
: jQuery.isArray(copy) ? [] : {}; // Never move original objects, clone them
target[ name ] = jQuery.extend( deep, clone, copy ); // Don't bring in undefined values
} else if ( copy !== undefined ) {
target[ name ] = copy;
}
}
}
} // Return the modified object
return target;
};
jQuery的扩展(extend)
注意:$.extend和$().extend,都是用这一个方法搞定的。
//extend
var obj1 = $.extend({}, { name: 'lk', age: 18 }, { weight: 120 })
var obj2 = $.extend({}, { name: 'lk', attr: { age: 15, hair: 'red' } }, { weight: 120 })
var obj3 = $.extend(false, { name: 'lk', attr: { age: 15, hair: 'red' } }, { weight: 120 }, { attr: { sight: 5.0 } })
console.log(obj3);//{name: "lk",weight: 120,attr:{sight: 5.0}}
var obj4 = $.extend(true, { name: 'lk', attr: { age: 15, hair: 'red' } }, { weight: 120 }, { attr: { age: 18, sight: 5.0 } })
console.log(obj4);//{name: "lk",weight: 120,attr:{age: 18, hair: 'red',sight: 5.0}}
extend使用
注意递归的使用:
function multi(num) {
//终止条件
if (num == 1) {
return 1;
} return num * multi(num - 1);//5*4*3*2*1 }
console.log(multi(5))//
递归,先递后归
//我们想把这个对象真正的复制一份出来
var obj1 = { a: 15 }
var obj2 = obj1;
obj1.a = 18;
console.log(obj2); //{a:18 }//想要的是讲obj1对象“拷贝”给obj2之后,改obj1,不会造成对obj2的影响。
拷贝就是采用的递归:
function copy(obj) {
var newObj = {} for (var key in obj) {
newObj[key] = obj[key]
}
return newObj; }
var obj4 = copy(obj3);
obj3.a = 18;
console.log(obj3)//{a:18}
console.log(obj4)//{a:20} 通过这种拷贝的形式,就会使得不会相互影响,脱离的“引用问题”干扰。
模拟一个浅拷贝
function deepCopy(obj) {
//终止条件,当不是{key:value}对象时
if (typeof obj != 'object') {
return obj;
}
var newObj = {}
for (var key in obj) {
newObj[key] = deepCopy(obj[key]);//“递”次调用,最后”归“一 }
return newObj; }
var obj8 = deepCopy(obj7);
obj7.a.b.c = 18;
console.log(obj7);//{ a: { b: { c: 18 } } }
console.log(obj8); //{ a: { b: { c: 15 } } }
模拟一个深拷贝
自己模仿一个扩展。
function Bird() {
this.wing = 2;
this.fly = function () {
alert("fly");
}
}
Bird.kuozhan = Bird.prototype.kuozhan = function (obj) {
for (var key in obj) {//{a:5,b:10}
this[key] = obj[key]
}
return this;
}
Bird.kuozhan=Bird.prototype.kuozhan =function(){}
//函数:既是方法,又是变量,还是对象。那么函数肯定有属性、方法
//扩展静态方法
//var Bird= function () { function Bird() {
this.wing = 2;
this.fly = function () {
alert("fly");
}
}
Bird.say = function () {
alert('say');
}
Bird.run = function () {
alert('run');
}
// Bird.fly();//这里出现错误,只能其实例调用
var bird = new Bird();
bird.fly(); Bird.say();//say
Bird.run();//run
//对一个方法对象扩展同时扩展多个方法(自己调用),更为方便的写法
//看一些框架中,把扩展的多个方法弄成一个对象,整体做参数,传进去,就把这个参数对象的方法一个一个扩展到原来对象上去了。就类似
//{fun1:function(){},fun2:function(){},fun3:function(){}},然后一自动对齐,显得逼格十足。
//要实现这点,下部如何将一个对象的方法一个一个扩展到原来对象上去呢?是的,我们就写出这个扩展方法。少用“=”,多用“:” Bird.kuozhan = Bird.prototype.kuozhan = function (obj) {
for (var key in obj) {//{a:5,b:10}
this[key] = obj[key]
}
return this;
}
Bird.kuozhan({
s: function () {
alert('1');
},
r: function () {
alert('2');
}
})
Bird.s();
Bird.r();
Bird.prototype.kuozhan({
m: function () {
alert('m');
},
n: function () {
alert('n');
}
})
var b = new Bird();
扩展使用
五,继承注意
/*引用的问题*/
/*********************************************************************/
/*数组*/
var a=[1,2,3];
var b=a;
//a.push(4);//修改的问题
b.push(4);//修改的问题
console.log(a);//[1,2,3,4]
console.log(b);//[1,2,3,4] var a=[1,2,3];
var b=a;
//=等号 :重开辟新空间重新赋值 开辟新空间导致 就不会再存在引用类型修改的问题
a=[7,8,9]
console.log(a);//[7,8,9]
console.log(b);//[1,2,3,4] /*********************************************************************/
/*object*/
var obj1={name:"老李"};
var obj2=obj1;
obj2.name="老王"
console.log(obj1);//{name:"老王"}
console.log(obj2);//{name:"老王"} var obj1={name:"老李"};
var obj2=obj1; obj2={haha:"笑哈哈"}
console.log(obj1);{name:"老李"}
console.log(obj2);{haha:"笑哈哈"} /*********************************************************************/
/*特殊的方法,不能修改*/
var a=function(){alert('qqqqq')}
var b=a;
//函数只能= 函数不能修改,不存在修改的问题
b=function(){alert('wwww')}
a();//qqqqq
b();//wwww
数组、Object、function,修改、重新赋值的问题
function Person(name, age) {
this.name = name;
this.age = age;
this.aler = function () {
alert(1);
}
}
Person.prototype = {//因为prototype是对象,可以写成无序键值对
sayHi: function () { alert('sayhi'); },
sayHello: function () { alert('sayhello'); }
}
function student(sname, sage) {//
Person.call(this, sname, sage);//we
}
//student.prototype = Person.prototype;
student.prototype = new Person();
student.prototype.constructor = student; var stu1 = new student();
stu1.aler();
stu1.sayHi();
stu1.sayHello();
继承勿忘修正构造函数指向
//student.prototype = Person.prototype;
student.prototype = new Person();//可以来个”父类“实例,因为原型链
student.prototype.constructor = student;//上面的代码已经破坏了原型的构造指向,勿忘修改。
jQuery系列:五个模块总结的更多相关文章
- jQuery系列 第八章 jQuery框架Ajax模块
第八章 jQuery框架Ajax模块 8.1 jQuery框架中的Ajax简介 Ajax技术的核心是XMLHTTPRequest对象,该对象是Ajax实现的关键,发送异步请求.接收服务器端的响应以及执 ...
- 爬虫系列(五) re的基本使用
1.简介 究竟什么是正则表达式 (Regular Expression) 呢?可以用下面的一句话简单概括: 正则表达式是一组特殊的 字符序列,由一些事先定义好的字符以及这些字符的组合形成,常常用于 匹 ...
- 网络结构解读之inception系列五:Inception V4
网络结构解读之inception系列五:Inception V4 在残差逐渐当道时,google开始研究inception和残差网络的性能差异以及结合的可能性,并且给出了实验结构. 本文思想阐述不多, ...
- Keil MDK STM32系列(五) 使用STM32CubeMX创建项目基础结构
Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...
- CSS 魔法系列:纯 CSS 绘制各种图形《系列五》
我们的网页因为 CSS 而呈现千变万化的风格.这一看似简单的样式语言在使用中非常灵活,只要你发挥创意就能实现很多比人想象不到的效果.特别是随着 CSS3 的广泛使用,更多新奇的 CSS 作品涌现出来. ...
- Netty4.x中文教程系列(五)编解码器Codec
Netty4.x中文教程系列(五)编解码器Codec 上一篇文章详细解释了ChannelHandler的相关构架设计,版本和设计逻辑变更等等. 这篇文章主要在于讲述Handler里面的Codec,也就 ...
- WCF编程系列(五)元数据
WCF编程系列(五)元数据 示例一中我们使用了scvutil命令自动生成了服务的客户端代理类: svcutil http://localhost:8000/?wsdl /o:FirstServic ...
- JVM系列五:JVM监测&工具
JVM系列五:JVM监测&工具[整理中] http://www.cnblogs.com/redcreen/archive/2011/05/09/2040977.html 前几篇篇文章介绍了介 ...
- SQL Server 2008空间数据应用系列五:数据表中使用空间数据类型
原文:SQL Server 2008空间数据应用系列五:数据表中使用空间数据类型 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Server 2008 R2调测 ...
- VSTO之旅系列(五):创建Outlook解决方案
原文:VSTO之旅系列(五):创建Outlook解决方案 本专题概要 引言 Outlook对象模型 自定义Outlook窗体 小结 一.引言 在上一个专题中,为大家简单介绍了下如何创建Word解决方案 ...
随机推荐
- spark streaming 接收 kafka 数据java代码WordCount示例
http://www.cnblogs.com/gaopeng527/p/4959633.html
- html嵌入样式表
1.针对文件中的字体还有属性进行设置主要设置文字的大小及其颜色问题,未涉及div飘操作 处理页面CSS 先检测该内容部分是否已经设定了样式,如果没有单独设定再按照总体设计进行限定. eg: h1 h ...
- UVA2037
#include<cstdio> int Sum(int n) { int sum=0; while(n!=0) { sum+=n%10; n/=10; } return sum; } v ...
- BZOJ 4582: [Usaco2016 Open]Diamond Collector
Descrirption 给你一个长度为 \(n\) 的序列,求将它分成两个序列后最多个数,每个序列最大值最小值不能超过 \(k\) Sol 二分+DP. 排一下序,找出以这个点结尾和开始的位置. 这 ...
- Eclipse自动编译问题
今天遇到一个很郁闷的问题,在程序中修改了一个String字符串,结果打断点是发现,还是修改之前的值,一点都没有变,最终发现该类在tomcat中的class的大小一直都没有变,只有修改时间在变,这才意识 ...
- HTTPS Web配置举例
http://www.h3c.com.cn/Products___Technology/Technology/Security_Encrypt/Other_technology/Representat ...
- Android错误
1. [2016-09-16 14:25:45 - X_Card] Found 2 versions of android-support-v4.jar in the dependency list, ...
- mongoTemplate简单用法(增删改查)
分页时查找数量: public long countSample(String id) { Query query = new Query(); if (StringUtil.hasText(id)) ...
- VC++ CString类完美总结(整理)
CString 是编程中一种非常有用的数据类型,它是MFC中的一个类,很大程度上简化了MFC中的许多字符串的操作. CString位于头文件afx.h中. ①.CString 类对象的初始化: CSt ...
- 水平时间轴 html + css
比较粗糙,效果如图 这个是写微信页面时写的,pc 也是一样的效果 代码如下: <div class="time_line_box"> <div class=&qu ...