jQuery源码分析-03构造jQuery对象-工具函数


Posted in Javascript onNovember 14, 2011

作者:nuysoft/高云 QQ:47214707 EMail:nuysoft@gmail.com
声明:本文为原创文章,如需转载,请注明来源并保留原文链接。
读读写写,不对的地方请告诉我,多多交流共同进步,本章的的PDF等本章写完了发布。
jQuery源码分析系列的目录请查看 http://nuysoft.iteye.com/blog/1177451,想系统的好好写写,目前还是从我感兴趣的部分开始,如果大家有对哪个模块感兴趣的,建议优先分析的,可以告诉我,一起学习。
3.4 其他静态工具函数

// 扩展工具函数 
jQuery.extend({ 
// 释放$的 jQuery 控制权 
// 许多 JavaScript 库使用 $ 作为函数或变量名,jQuery 也一样。 
// 在 jQuery 中,$ 仅仅是 jQuery 的别名,因此即使不使用 $ 也能保证所有功能性。 
// 假如我们需要使用 jQuery 之外的另一 JavaScript 库,我们可以通过调用 $.noConflict() 向该库返回控制权。 
// 通过向该方法传递参数 true,我们可以将 $ 和 jQuery 的控制权都交还给另一JavaScript库。 
noConflict: function( deep ) { 
// 交出$的控制权 
if ( window.$ === jQuery ) { 
window.$ = _$; 
} 
// 交出jQuery的控制权 
if ( deep && window.jQuery === jQuery ) { 
window.jQuery = _jQuery; 
} 
return jQuery; 
}, 
// Is the DOM ready to be used? Set to true once it occurs. 
isReady: false, 
// A counter to track how many items to wait for before 
// the ready event fires. See #6781 
// 一个计数器,用于跟踪在ready事件出发前的等待次数 
readyWait: 1, 
// Hold (or release) the ready event 
// 继续等待或触发 
holdReady: function( hold ) { 
if ( hold ) { 
jQuery.readyWait++; 
} else { 
jQuery.ready( true ); 
} 
}, 
// Handle when the DOM is ready 
// 文档加载完毕句柄 
ready: function( wait ) { 
// Either a released hold or an DOMready/load event and not yet ready 
// 
if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { 
// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). 
// 确保document.body存在 
if ( !document.body ) { 
return setTimeout( jQuery.ready, 1 ); 
} 
// Remember that the DOM is ready 
jQuery.isReady = true; 
// If a normal DOM Ready event fired, decrement, and wait if need be 
if ( wait !== true && --jQuery.readyWait > 0 ) { 
return; 
} 
// If there are functions bound, to execute 
readyList.resolveWith( document, [ jQuery ] ); 
// Trigger any bound ready events 
if ( jQuery.fn.trigger ) { 
jQuery( document ).trigger( "ready" ).unbind( "ready" ); 
} 
} 
}, 
// 初始化readyList事件处理函数队列 
// 兼容不同浏览对绑定事件的区别 
bindReady: function() { 
if ( readyList ) { 
return; 
} 
readyList = jQuery._Deferred(); 
// Catch cases where $(document).ready() is called after the 
// browser event has already occurred. 
if ( document.readyState === "complete" ) { 
// Handle it asynchronously to allow scripts the opportunity to delay ready 
return setTimeout( jQuery.ready, 1 ); 
} 
// Mozilla, Opera and webkit nightlies currently support this event 
// 兼容事件,通过检测浏览器的功能特性,而非嗅探浏览器 
if ( document.addEventListener ) { 
// Use the handy event callback 
// 使用较快的加载完毕事件 
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); 
// A fallback to window.onload, that will always work 
// 注册window.onload回调函数 
window.addEventListener( "load", jQuery.ready, false ); 
// If IE event model is used 
} else if ( document.attachEvent ) { 
// ensure firing before onload, 
// maybe late but safe also for iframes 
// 确保在onload之前触发onreadystatechange,可能慢一些但是对iframes更安全 
document.attachEvent( "onreadystatechange", DOMContentLoaded ); 
// A fallback to window.onload, that will always work 
// 注册window.onload回调函数 
window.attachEvent( "onload", jQuery.ready ); 
// If IE and not a frame 
// continually check to see if the document is ready 
var toplevel = false; 
try { 
toplevel = window.frameElement == null; 
} catch(e) {} 
if ( document.documentElement.doScroll && toplevel ) { 
doScrollCheck(); 
} 
} 
}, 
// See test/unit/core.js for details concerning isFunction. 
// Since version 1.3, DOM methods and functions like alert 
// aren't supported. They return false on IE (#2968). 
// 是否函数 
isFunction: function( obj ) { 
return jQuery.type(obj) === "function"; 
}, 
// 是否数组 
// 如果浏览器有内置的 Array.isArray 实现,就使用浏览器自身的实现方式, 
// 否则将对象转为String,看是否为"[object Array]"。 
isArray: Array.isArray || function( obj ) { 
return jQuery.type(obj) === "array"; 
}, 
// A crude way of determining if an object is a window 
// 简单的判断(判断setInterval属性)是否window对象 
isWindow: function( obj ) { 
return obj && typeof obj === "object" && "setInterval" in obj; 
}, 
// 是否是保留字NaN 
isNaN: function( obj ) { 
// 等于null 或 不是数字 或调用window.isNaN判断 
return obj == null || !rdigit.test( obj ) || isNaN( obj ); 
}, 
// 获取对象的类型 
type: function( obj ) { 
// 通过核心API创建一个对象,不需要new关键字 
// 普通函数不行 
// 调用Object.prototype.toString方法,生成 "[object Xxx]"格式的字符串 
// class2type[ "[object " + name + "]" ] = name.toLowerCase(); 
return obj == null ? 
String( obj ) : 
class2type[ toString.call(obj) ] || "object"; 
}, 
// 检查obj是否是一个纯粹的对象(通过"{}" 或 "new Object"创建的对象) 
// console.info( $.isPlainObject( {} ) ); // true 
// console.info( $.isPlainObject( '' ) ); // false 
// console.info( $.isPlainObject( document.location ) ); // true 
// console.info( $.isPlainObject( document ) ); // false 
// console.info( $.isPlainObject( new Date() ) ); // false 
// console.info( $.isPlainObject( ) ); // false 
// isPlainObject分析与重构 https://3water.com/article/25047.htm 
// 对jQuery.isPlainObject()的理解 http://www.cnblogs.com/phpmix/articles/1733599.html 
isPlainObject: function( obj ) { 
// Must be an Object. 
// Because of IE, we also have to check the presence of the constructor property. 
// Make sure that DOM nodes and window objects don't pass through, as well 
// 必须是一个对象 
// 因为在IE8中会抛出非法指针异常,必须检查constructor属性 
// DOM节点和window对象,返回false 
// obj不存在 或 非object类型 或 DOM节点 或 widnow对象,直接返回false 
// 测试以下三中可能的情况: 
// jQuery.type(obj) !== "object" 类型不是object,忽略 
// obj.nodeType 认为DOM节点不是纯对象 
// jQuery.isWindow( obj ) 认为window不是纯对象 
if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { 
return false; 
} 
// Not own constructor property must be Object 
// 测试constructor属性 
// 具有构造函数constructor,却不是自身的属性(即通过prototype继承的), 
if ( obj.constructor && 
!hasOwn.call(obj, "constructor") && 
!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { 
return false; 
} 
// Own properties are enumerated firstly, so to speed up, 
// if last one is own, then all properties are own. 
var key; 
for ( key in obj ) {} 
// key === undefined及不存在任何属性,认为是简单的纯对象 
// hasOwn.call( obj, key ) 属性key不为空,且属性key的对象自身的(即不是通过prototype继承的) 
return key === undefined || hasOwn.call( obj, key ); 
}, 
// 是否空对象 
isEmptyObject: function( obj ) { 
for ( var name in obj ) { 
return false; 
} 
return true; 
}, 
// 抛出一个异常 
error: function( msg ) { 
throw msg; 
}, 
// 解析JSON 
// parseJSON把一个字符串变成JSON对象。 
// 我们一般使用的是eval。parseJSON封装了这个操作,但是eval被当作了最后手段。 
// 因为最新JavaScript标准中加入了JSON序列化和反序列化的API。 
// 如果浏览器支持这个标准,则这两个API是在JS引擎中用Native Code实现的,效率肯定比eval高很多。 
// 目前来看,Chrome和Firefox4都支持这个API。 
parseJSON: function( data ) { 
if ( typeof data !== "string" || !data ) { 
return null; 
} 
// Make sure leading/trailing whitespace is removed (IE can't handle it) 
data = jQuery.trim( data ); 
// Attempt to parse using the native JSON parser first 
// 原生JSON API。反序列化是JSON.stringify(object) 
if ( window.JSON && window.JSON.parse ) { 
return window.JSON.parse( data ); 
} 
// Make sure the incoming data is actual JSON 
// Logic borrowed from http://json.org/json2.js 
// ... 大致地检查一下字符串合法性 
if ( rvalidchars.test( data.replace( rvalidescape, "@" ) 
.replace( rvalidtokens, "]" ) 
.replace( rvalidbraces, "")) ) { 
return (new Function( "return " + data ))(); 
} 
jQuery.error( "Invalid JSON: " + data ); 
}, 
// Cross-browser xml parsing 
// (xml & tmp used internally) 
// 解析XML 跨浏览器 
// parseXML函数也主要是标准API和IE的封装。 
// 标准API是DOMParser对象。 
// 而IE使用的是Microsoft.XMLDOM的 ActiveXObject对象。 
parseXML: function( data , xml , tmp ) { 
if ( window.DOMParser ) { // Standard 标准XML解析器 
tmp = new DOMParser(); 
xml = tmp.parseFromString( data , "text/xml" ); 
} else { // IE IE的XML解析器 
xml = new ActiveXObject( "Microsoft.XMLDOM" ); 
xml.async = "false"; 
xml.loadXML( data ); 
} 
tmp = xml.documentElement; 
if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) { 
jQuery.error( "Invalid XML: " + data ); 
} 
return xml; 
}, 
// 无操作函数 
noop: function() {}, 
// Evaluates a script in a global context 
// Workarounds based on findings by Jim Driscoll 
// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context 
// globalEval函数把一段脚本加载到全局context(window)中。 
// IE中可以使用window.execScript。 
// 其他浏览器 需要使用eval。 
// 因为整个jQuery代码都是一整个匿名函数,所以当前context是jQuery,如果要将上下文设置为window则需使用globalEval。 
globalEval: function( data ) { 
// data非空 
if ( data && rnotwhite.test( data ) ) { 
// We use execScript on Internet Explorer 
// We use an anonymous function so that context is window 
// rather than jQuery in Firefox 
( window.execScript || function( data ) { 
window[ "eval" ].call( window, data ); 
} )( data ); 
} 
}, 
// 判断节点名称是否相同 
nodeName: function( elem, name ) { 
// 忽略大小写 
return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); 
}, 
// args is for internal usage only 
// 遍历对象或数组 
each: function( object, callback, args ) { 
var name, i = 0, 
length = object.length, 
isObj = length === undefined || jQuery.isFunction( object ); 
// 如果有参数args,调用apply,上下文设置为当前遍历到的对象,参数使用args 
if ( args ) { 
if ( isObj ) { 
for ( name in object ) { 
if ( callback.apply( object[ name ], args ) === false ) { 
break; 
} 
} 
} else { 
for ( ; i < length; ) { 
if ( callback.apply( object[ i++ ], args ) === false ) { 
break; 
} 
} 
} 
// A special, fast, case for the most common use of each 
// 没有参数args则调用,则调用call,上下文设置为当前遍历到的对象,参数设置为key/index和value 
} else { 
if ( isObj ) { 
for ( name in object ) { 
if ( callback.call( object[ name ], name, object[ name ] ) === false ) { 
break; 
} 
} 
} else { 
for ( ; i < length; ) { 
if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { 
break; 
} 
} 
} 
} 
return object; 
}, 
// Use native String.trim function wherever possible 
// 尽可能的使用本地String.trim方法,否则先过滤开头的空格,再过滤结尾的空格 
trim: trim ? 
function( text ) { 
return text == null ? 
"" : 
trim.call( text ); 
} : 
// Otherwise use our own trimming functionality 
function( text ) { 
return text == null ? 
"" : 
text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); 
}, 
// results is for internal usage only 
// 将伪数组转换为数组 
makeArray: function( array, results ) { 
var ret = results || []; 
if ( array != null ) { 
// The window, strings (and functions) also have 'length' 
// The extra typeof function check is to prevent crashes 
// in Safari 2 (See: #3039) 
// Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 
// 一大堆浏览器兼容性测试,真实蛋疼 
var type = jQuery.type( array ); 
// 测试:有没有length属性、字符串、函数、正则 
// 不是数组,连伪数组都不是 
if ( array.length == null 
|| type === "string" 
|| type === "function" 
|| type === "regexp" 
|| jQuery.isWindow( array ) ) { 
push.call( ret, array ); 
} else { 
// $.type( $('div') ) // object 
jQuery.merge( ret, array ); 
} 
} 
return ret; 
}, 
// 
inArray: function( elem, array ) { 
// 是否有本地化的Array.prototype.indexOf 
if ( indexOf ) { 
// 直接调用Array.prototype.indexOf 
return indexOf.call( array, elem ); 
} 
// 遍历数组,查找是否有完全相等的元素,并返回下标 
// 循环的小技巧:把array.length存放到length变量中,可以减少一次作用域查找 
for ( var i = 0, length = array.length; i < length; i++ ) { 
if ( array[ i ] === elem ) { 
return i; 
} 
} 
// 如果返回-1,则表示不在数组中 
return -1; 
}, 
// 将数组second合并到数组first中 
merge: function( first, second ) { 
var i = first.length, // 
j = 0; 
// 如果second的length属性是Number类型,则把second当数组处理 
if ( typeof second.length === "number" ) { 
for ( var l = second.length; j < l; j++ ) { 
first[ i++ ] = second[ j ]; 
} 
} else { 
// 遍历second,将非undefined的值添加到first中 
while ( second[j] !== undefined ) { 
first[ i++ ] = second[ j++ ]; 
} 
} 
// 修正first的length属性,因为first可能不是真正的数组 
first.length = i; 
return first; 
}, 
// 过滤数组,返回新数组;callback返回true时保留;如果inv为true,callback返回false才会保留 
grep: function( elems, callback, inv ) { 
var ret = [], retVal; 
inv = !!inv; 
// Go through the array, only saving the items 
// that pass the validator function 
// 遍历数组,只保留通过验证函数callback的元素 
for ( var i = 0, length = elems.length; i < length; i++ ) { 
// 这里callback的参数列表为:value, index,与each的习惯一致 
retVal = !!callback( elems[ i ], i ); 
// 是否反向选择 
if ( inv !== retVal ) { 
ret.push( elems[ i ] ); 
} 
} 
return ret; 
}, 
// arg is for internal usage only 
// 将数组或对象elems的元素/属性,转化成新的数组 
map: function( elems, callback, arg ) { 
var value, key, ret = [], 
i = 0, 
length = elems.length, 
// jquery objects are treated as arrays 
// 检测elems是否是(伪)数组 
// 1. 将jQuery对象也当成数组处理 
// 2. 检测length属性是否存在,length等于0,或第一个和最后一个元素是否存在,或jQuery.isArray返回true 
isArray = elems instanceof jQuery 
|| length !== undefined && typeof length === "number" 
&& ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; 
// 是数组或对象的差别,仅仅是遍历的方式不同,没有其他的区别 
// Go through the array, translating each of the items to their 
// 遍历数组,对每一个元素调用callback,将返回值不为null的值,存入ret 
if ( isArray ) { 
for ( ; i < length; i++ ) { 
// 执行callback,参数依次为value, index, arg 
value = callback( elems[ i ], i, arg ); 
// 如果返回null,则忽略(无返回值的function会返回undefined) 
if ( value != null ) { 
ret[ ret.length ] = value; 
} 
} 
// Go through every key on the object, 
// 遍历对象,对每一个属性调用callback,将返回值不为null的值,存入ret 
} else { 
for ( key in elems ) { 
// 执行callback,参数依次为value, key, arg 
value = callback( elems[ key ], key, arg ); 
// 同上 
if ( value != null ) { 
ret[ ret.length ] = value; 
} 
} 
} 
// Flatten any nested arrays 
// 使嵌套数组变平 
// concat: 
// 如果某一项为数组,那么添加其内容到末尾。 
// 如果该项目不是数组,就将其作为单个的数组元素添加到数组的末尾。 
return ret.concat.apply( [], ret ); 
}, 
// A global GUID counter for objects 
guid: 1, 
// Bind a function to a context, optionally partially applying any 
// arguments. 
// 代理方法:为fn指定上下文(即this) 
// jQuery.proxy( function, context ) 
// jQuery.proxy( context, name ) 
proxy: function( fn, context ) { 
// 如果context是字符串,设置上下文为fn,fn为fn[ context ] 
// 即设置fn的context方法的上下文为fn(默认不是这样吗???TODO) 
if ( typeof context === "string" ) { 
var tmp = fn[ context ]; 
context = fn; 
fn = tmp; 
} 
// Quick check to determine if target is callable, in the spec 
// this throws a TypeError, but we will just return undefined. 
// 快速测试fn是否是可调用的(即函数),在文档说明中,会抛出一个TypeError, 
// 但是这里仅返回undefined 
if ( !jQuery.isFunction( fn ) ) { 
return undefined; 
} 
// Simulated bind 
var args = slice.call( arguments, 2 ), // 从参数列表中去掉fn,context 
proxy = function() { 
// 设置上下文为context和参数 
return fn.apply( context, args.concat( slice.call( arguments ) ) ); 
}; 
// Set the guid of unique handler to the same of original handler, so it can be removed 
// 统一guid,使得proxy能够被移除 
proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; 
return proxy; 
}, 
// Mutifunctional method to get and set values to a collection 
// The value/s can be optionally by executed if its a function 
// 多功能函数,读取或设置集合的属性值;值为函数时会被执行 
// fn:jQuery.fn.css, jQuery.fn.attr, jQuery.fn.prop 
access: function( elems, key, value, exec, fn, pass ) { 
var length = elems.length; 
// Setting many attributes 
// 如果有多个属性,则迭代 
if ( typeof key === "object" ) { 
for ( var k in key ) { 
jQuery.access( elems, k, key[k], exec, fn, value ); 
} 
return elems; 
} 
// Setting one attribute 
// 只设置一个属性 
if ( value !== undefined ) { 
// Optionally, function values get executed if exec is true 
exec = !pass && exec && jQuery.isFunction(value); 
for ( var i = 0; i < length; i++ ) { 
fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); 
} 
return elems; 
} 
// Getting an attribute 
// 读取属性 
return length ? fn( elems[0], key ) : undefined; 
}, 
// 获取当前时间的便捷函数 
now: function() { 
return (new Date()).getTime(); 
}, 
// Use of jQuery.browser is frowned upon. 
// More details: http://docs.jquery.com/Utilities/jQuery.browser 
// 不赞成使用jQuery.browser,推荐使用jQuery.support 
// Navigator 正在使用的浏览器的信息 
// Navigator.userAgent 一个只读的字符串,声明了浏览器用于HTPP请求的用户代理头的值 
uaMatch: function( ua ) { 
ua = ua.toLowerCase(); 
// 依次匹配各浏览器 
var match = rwebkit.exec( ua ) || 
ropera.exec( ua ) || 
rmsie.exec( ua ) || 
ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || 
[]; 
// match[1] || "" 
// match[1]为false(空字符串、null、undefined、0等)时,默认为"" 
// match[2] || "0" 
// match[2]为false(空字符串、null、undefined、0等)时,默认为"0" 
return { browser: match[1] || "", version: match[2] || "0" }; 
}, 
// 创建一个新的jQuery副本,副本的属性和方法可以被改变,但是不会影响原始的jQuery对象 
// 有两种用法: 
// 1. 覆盖jQuery的方法,而不破坏原始的方法 
// 2.封装,避免命名空间冲突,可以用来开发jQuery插件 
// 值得注意的是,jQuery.sub()函数并不提供真正的隔离,所有的属性、方法依然指向原始的jQuery 
// 如果使用这个方法来开发插件,建议优先考虑jQuery UI widget工程 
sub: function() { 
function jQuerySub( selector, context ) { 
return new jQuerySub.fn.init( selector, context ); 
} 
jQuery.extend( true, jQuerySub, this ); // 深度拷贝,将jQuery的所有属性和方法拷贝到jQuerySub 
jQuerySub.superclass = this; 
jQuerySub.fn = jQuerySub.prototype = this(); // 
jQuerySub.fn.constructor = jQuerySub; 
jQuerySub.sub = this.sub; 
jQuerySub.fn.init = function init( selector, context ) { 
if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { 
context = jQuerySub( context ); 
} 
return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); 
}; 
jQuerySub.fn.init.prototype = jQuerySub.fn; 
var rootjQuerySub = jQuerySub(document); 
return jQuerySub; 
}, 
// 浏览器类型和版本: 
// $.browser.msie/mozilla/webkit/opera 
// $.browser.version 
// 不推荐嗅探浏览器类型jQuery.browser,而是检查浏览器的功能特性jQuery.support 
// 未来jQuery.browser可能会移到一个插件中 
browser: {} 
});
Javascript 相关文章推荐
添加到收藏夹代码(兼容几乎所有的浏览器)
Jan 09 Javascript
阻止子元素继承父元素事件具体思路及实现
May 02 Javascript
Javascript 拖拽雏形中的一些问题(逐行分析代码,让你轻松了拖拽的原理)
Jan 23 Javascript
jQuery实现淡入淡出二级下拉导航菜单的方法
Aug 28 Javascript
apply和call方法定义及apply和call方法的区别
Nov 15 Javascript
Jquery和angularjs获取check框选中的值的方法汇总
Jan 17 Javascript
浅谈JS函数节流防抖
Oct 18 Javascript
JS实现运动缓冲效果的封装函数示例
Feb 18 Javascript
js实现文字头像的生成代码
Mar 07 Javascript
Vue跨域请求问题解决方案过程解析
Aug 07 Javascript
在vscode 中设置 vue模板内容的方法
Sep 02 Javascript
JS如何操作DOM基于表格动态展示数据
Oct 15 Javascript
jQuery源码分析-03构造jQuery对象-源码结构和核心函数
Nov 14 #Javascript
jQuery源码分析-02正则表达式 RegExp 常用正则表达式
Nov 14 #Javascript
jQuery源码分析-01总体架构分析
Nov 14 #Javascript
js Form.elements[i]的使用实例
Nov 13 #Javascript
jquery中使用ajax获取远程页面信息
Nov 13 #Javascript
JQuery模板插件 jquery.tmpl 动态ajax扩展
Nov 10 #Javascript
jBox 2.3基于jquery的最新多功能对话框插件 常见使用问题解答
Nov 10 #Javascript
You might like
数据库的日期格式转换
2006/10/09 PHP
php读取文件内容的几种方法详解
2013/06/26 PHP
PHP二维数组排序的3种方法和自定义函数分享
2014/04/09 PHP
php封装的图片(缩略图)处理类完整实例
2016/10/19 PHP
中文路径导致unitpngfix.js不正常的解决方法
2013/06/26 Javascript
JS判定是否原生方法
2013/07/22 Javascript
分享jQuery封装好的一些常用操作
2016/07/28 Javascript
jQuery+pjax简单示例汇总
2017/04/21 jQuery
深入理解Webpack 中路径的配置
2017/06/17 Javascript
使用 jQuery 实现表单验证功能
2017/07/05 jQuery
C#实现将一个字符转换为整数
2017/12/12 Javascript
vue封装自定义指令之动态显示title操作(溢出显示,不溢出不显示)
2020/11/12 Javascript
[46:57]EG vs Winstrike 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
Python set集合类型操作总结
2014/11/07 Python
Python通过future处理并发问题
2017/10/17 Python
Python+树莓派+YOLO打造一款人工智能照相机
2018/01/02 Python
python 信息同时输出到控制台与文件的实例讲解
2018/05/11 Python
对Python 窗体(tkinter)文本编辑器(Text)详解
2018/10/11 Python
Pycharm 文件更改目录后,执行路径未更新的解决方法
2019/07/19 Python
详解如何从TensorFlow的mnist数据集导出手写体数字图片
2019/08/05 Python
pytorch 模拟关系拟合——回归实例
2020/01/14 Python
Python文字截图识别OCR工具实例解析
2020/03/05 Python
Python 使用 PyQt5 开发的关机小工具分享
2020/07/16 Python
Hotels.com中国区:好订网
2016/08/18 全球购物
VICHY薇姿英国官网:全球专业敏感肌护肤领先品牌
2017/07/04 全球购物
俄罗斯护发和专业化妆品购物网站:Hihair
2019/09/28 全球购物
工作睡觉检讨书
2014/02/25 职场文书
学习雷锋标语
2014/06/25 职场文书
县政府领导班子“四风”方面突出问题整改措施
2014/09/23 职场文书
基层党员四风问题自我剖析材料
2014/09/29 职场文书
英语感谢信范文
2015/01/20 职场文书
2016年春季开学典礼新闻稿
2015/11/25 职场文书
小学语文教学反思范文
2016/03/03 职场文书
一文帮你理解PReact10.5.13源码
2021/04/03 Javascript
windows11怎么查看wifi密码? win11查看wifi密码的技巧
2021/11/21 数码科技
Python调用腾讯API实现人脸身份证比对功能
2022/04/04 Python