[Introduction] Underscore js source code Underscore js does not extend the native JavaScript object, but encapsulates it by calling the _() method. Once the encapsulation is completed, the native JavaScript object becomes an Underscore object. Determine whether a given variable is an object Is
Underscore.js
does not extend the native JavaScript
object, but passes Call the _()
method to encapsulate. Once the encapsulation is completed, the native JavaScript
object becomes an Underscore
object.
// Is a given variable an object? _.isObject = function(obj) { var type = typeof obj; return type === 'function' || type === 'object' && !!obj; };
This is a source code for underscore.js
to judge whether a given variable is an object
. We know that typeof
will return the following six values:
1. 'undefined' --- 这个值未定义;2. 'boolean' --- 这个值是布尔值;3. 'string' --- 这个值是字符串;4. 'number' --- 这个值是数值;5. 'object' --- 这个值是对象或null;6. 'function' --- 这个值是函数。
and &&
has a higher priority than ||
. !!
is equivalent to Boolean()
, converting it to a Boolean value.
// Is a given value a DOM element? _.isElement = function(obj) { return !!(obj && obj.nodeType === 1); };
Similarly !!
Equivalent to Boolean()
, nodeType == = 1
means it is an element node, the attribute attr
is 2, and the text text
is 3
<body> <p id="test">测试</p><script> var t = document.getElementById('test'); alert(t.nodeType);//1 alert(t.nodeName);//p alert(t.nodeValue);//null</script></body>
firstChild
Attribute
var t = document.getElementById('test').firstChild; alert(t.nodeType);//3alert(t.nodeName);//#testalert(t.nodeValue);//测试
The text node is also a node, so the child node of p is the text node, so return 3
isArray = Array.isArray || function(object){ return object instanceof Array }
Array.isArray()
Method: Returns true
if an object is an array, and false
if not.
instanceof
Used to determine whether a variable is an instance of an object, such as
var a= []; alert(a instanceof Array);//返回 true
At the same time, alert(a instanceof Object)
will also returntrue
##isArray Returns a Boolean value. If
Array.isArray is
true, then
true## is returned. #, otherwise return the result of object instanceof Array
. Data type judgment
class2type = {},function type(obj) { return obj == null ? String(obj) : class2type[toString.call(obj)] || "object" } function isFunction(value) { return type(value) == "function" } function isWindow(obj) { return obj != null && obj == obj.window } function isDocument(obj) { return obj != null && obj.nodeType == obj.DOCUMENT_NODE } function isObject(obj) { return type(obj) == "object" }
is an empty object. In fact, an empty object with nothing is created like thisObject.create(null) ;
We can determine the data type through the
method, for example: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="hljs javascript">console.log(Object.prototype.toString.call(123)) //[object Number] console.log(Object.prototype.toString.call(&#39;123&#39;)) //[object String] console.log(Object.prototype.toString.call(undefined)) //[object Undefined] console.log(Object.prototype.toString.call(true)) //[object Boolean] console.log(Object.prototype.toString.call({})) //[object Object] console.log(Object.prototype.toString.call([])) //[object Array] console.log(Object.prototype.toString.call(function(){})) //[object Function]</pre><div class="contentsignin">Copy after login</div></div>
First if the parameter
is undefined
or null
, then use String(obj)
to convert it to the corresponding original string "undefined
" or " null
”. Then
First borrow the prototype method of Object
toString()
to get obj# The string representation of ##, the return value is in the form
[object class], where
class is the internal object class.
Then take out the lowercase string corresponding to
[object class]
class2type and return it; if it is not retrieved, it will always return "
object.
get method
get: function(idx){ return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length] },
idx is equal to
idx +length,
length is the length of the collection.
Maybe you are confused when you just saw
slice.call(this)
, including jQuery
, and the source code of backbone
are written like this, except that they make a statement at the beginning: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="hljs php">var push = array.push;var slice = array.slice;var splice = array.splice;</pre><div class="contentsignin">Copy after login</div></div>
Soslice.call(this)
In fact, it is still
prototype.js source code
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="hljs javascript"> //为对象添加 class 属性值
addClassName: function(element, className) {
element = $(element);
Element.removeClassName(element, className);
element.className += &#39; &#39; + className;
}, //为对象移除 class 属性值
removeClassName: function(element, className) {
element = $(element); if (!element) return; var newClassName = &#39;&#39;; var a = element.className.split(&#39; &#39;); for (var i = 0; i < a.length; i++) { if (a[i] != className) { if (i > 0)
newClassName += &#39; &#39;;
newClassName += a[i];
}
}
element.className = newClassName;
},</pre><div class="contentsignin">Copy after login</div></div>
because
, so analyze the latter first, $()
first encapsulates the elements into prototype
objects, <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="hljs coffeescript">if(!element) return</pre><div class="contentsignin">Copy after login</div></div>
The meaning of this sentence is that if the element object does not exist, it will be ignored and the execution will not continue, which means to terminate. <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="hljs perl">split() 方法用于把一个字符串分割成字符串数组。</pre><div class="contentsignin">Copy after login</div></div>
If the empty string (
) is used as a separator, then each character in the object will be separated
Determine whether it has a class attribute value<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="hljs javascript">//是否拥有 class 属性值hasClassName: function(element, className) {
element = $(element); if (!element) return; var a = element.className.split(&#39; &#39;); for (var i = 0; i < a.length; i++) { if (a[i] == className) return true;//返回正确的处理结果
} return false;//返回错误的处理结果},</pre><div class="contentsignin">Copy after login</div></div>
Compatible with older version browsers to add Array push. Method
/** * 为兼容旧版本的浏览器增加 Array 的 push 方法。 */if (!Array.prototype.push) { Array.prototype.push = function() { var startLength = this.length;//this指代Array for (var i = 0; i < arguments.length; i++) this[startLength + i] = arguments[i];//this依旧指代Array return this.length; } }
, it means that the browser does not support this method, and this[startLength + will be executed. i] = arguments[i]
Put each parameter passed in into the array in turn, and finally return the length of the arrayYou can use the
(.)
notation to access the object, You can also use
to access. Similarly, accessing array elements is also jQuery source code
toArray method<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="hljs javascript">jQuery.prototype = {
toArray: function() { return slice.call( this );
},
}</pre><div class="contentsignin">Copy after login</div></div>
arguments objects and convert it into an array. For example:
<script> var a = {length:4,0:'zero',1:'one',2:'two'}; console.log(Array.prototype.slice.call(a));// Array [ "zero", "one", "two", <1 个空的存储位置> ]</script>
Array
This is the base object name we want prototype
This can be thought of as a Namespace of instance methods of array
slice
这提取数组的一部分并返回新的数组,并没有开始和结束索引,它只是返回一个数组的拷贝
call
这是一个非常有用的功能,它允许你从一个对象调用一个函数并且使用它在另一个上下文环境
下面的写法是等效的:
Array.prototype.slice.call == [].slice.call
看这个例子:
object1 = { name:'frank', greet:function(){ alert('hello '+this.name) } }; object2 = { name:'trigkit4'};// object2没有greet方法// 但我们可以从object1中借来 object1.greet.call(object2);//弹出hello trigkit4
分解一下就是object1.greet
运行弹出hello + 'this.name'
,然后object2
对象冒充,this
就指代object2
var t = function(){ console.log(this);// String [ "t", "r", "i", "g", "k", "i", "t", "4" ] console.log(typeof this); // Object console.log(this instanceof String); // true}; t.call('trigkit4');
call(this)
指向了所传进去的对象。
在Object.prototype
中已经包含了一些方法:
1.toString ( ) 2.toLocaleString ( ) 3.valueOf ( ) 4.hasOwnProperty (V) 5.isPrototypeOf (V) 6.propertyIsEnumerable (V)
jQuery.fn.extend({ on: function( types, selector, data, fn, /*INTERNAL*/ one ) { var type, origFn; // Types can be a map of types/handlers if ( typeof types === "object" ) { // ( types-Object, selector, data ) if ( typeof selector !== "string" ) { // ( types-Object, data ) data = data || selector; selector = undefined; } } }) jQuery.extend(object) :为扩展jQuery类本身.为类添加新的方法。 jQuery.fn.extend(object) :给jQuery对象添加方法。
!=
在表达式两边的数据类型不一致时,会隐式转换为相同数据类型,然后对值进行比较.!==
不会进行类型转换,在比较时除了对值进行比较以外,还比较两边的数据类型, 它是恒等运算符===
的非形式。
on : function(){}
是js
对象字面量的写法
{键:值,键:值}
语法中的“健/值”
会成为对象的静态成员。如果给某个“健”指定的值是一个匿名函数,那么该函数就会变成对象的静态方法;否则就是对象的一个静态属性。
type: function( obj ) { if ( obj == null ) { return obj + ""; } return typeof obj === "object" || typeof obj === "function" ? class2type[ toString.call(obj) ] || "object" : typeof obj; },
前面已经分析了,class2type = {};
所以class2type[ toString.call(obj) ]
={}.toString.call(obj)
。它的作用是改变toString
的this
指向为object
的实例。
The above is the detailed content of Source code research on js framework. For more information, please follow other related articles on the PHP Chinese website!