8

因为 jQuery 是一种广泛使用且成熟的协作成果,所以我不禁要查看它的源代码,以获得编写更好的 Javascript 的指导。我一直在使用 jQuery 库和我的 PHP 应用程序,但是当我深入了解这个相当复杂的库时,我意识到我对 Javascript 仍然不了解。瞧,我有几个问题要问 SO 社区。首先,考虑以下代码......

$('#element').attr('alt', 'Ivan is SUPER hungry! lolz');

对比

$('#element').attr({'alt': 'Ivan is an ugly monster! omfgz'});

现在,这是说该attr()方法被设计为接受一个属性名称、一个属性名称和一个值,或者一个对值映射?有人可以简要解释一下地图实际上是什么以及它与 Javascript 中的数组不同的重要方式吗?

继续前进,整个图书馆都沉浸在这项业务中……

(function(window, undefined) { /* jQuery */ })(window);

我知道包裹的括号会导致类似于 的行为body onLoad="function();",但是这种做法称为什么,它与使用onLoad事件处理程序有什么不同吗?此外,我无法(window)在最后做出正面或反面。这里的对象到底发生了window什么?

我认为对象与 Javascript 中的函数没有什么不同是错误的吗?如果我错了,请纠正我$(),但它是包罗万象的 jQuery 对象,但它看起来就像一个方法。这是另一个带有代码示例的快速问题...

$('#element').attr('alt', 'Adopt a Phantom Cougar from Your Local ASPCA');

...内部应该看起来像这样(也许我错了)...

function $(var element = null) {
    if (element != null) {
        function attr(var attribute = null, var value = null) {
            /* stuff that does things */
        }
    }
}

这是在 Javascript 中定义对象及其子方法和属性的常规程序吗?比较 Javascript 和 PHP,您是否使用与从对象中检索方法.相同的方式使用句点?->

对于这有点冗长,我深表歉意,但是对这些问题的回答将向我揭示关于 jQuery 和 Javascript 的大量信息。谢谢!

4

4 回答 4

2

1.方法重载

$('#element').attr('alt', 'Ivan is SUPER hungry! lolz');

对比

$('#element').attr({'alt': 'Ivan is an ugly monster! omfgz'});

var attr = function (key, value) {
  // is first argument an object / map ?
  if (typeof key === "object") {
    // for each key value pair
    for (var k in key) {
      // recursively call it.
      attr(k, key[k]);
    }
  } else {
    // do magic with key and value
  }
}

2. 闭包

(function(window, undefined) { /* jQuery */ })(window);

不用作onload处理程序。它只是在函数内创建新范围。

这意味着这var foo是一个局部变量而不是全局变量。它还创建了一个undefined要使用的真实变量,因为未指定的参数传入undefined

这说明了window.undefined = true有效/允许的情况。

最后的(窗口)位。这里的窗口对象到底发生了什么?

它通过本地化来优化窗口访问。局部变量访问比全局变量访问快约 0.01%

我认为对象与 Javascript 中的函数没有什么不同是错误的吗?

是和不是。所有函数都是对象。$()只返回一个新的 jQuery 对象,因为它在内部调用return new jQuery.fn.init();

3. 你的片段

function $(var element = null) {

Javascript 不支持默认参数值或可选参数。模仿这一点的标准做法如下

function f(o) {
  o != null || (o = "default");
}

将 Javascript 与 PHP 进行比较,您是否使用句点 . 与您使用 -> 从对象中检索方法的方式相同吗?

您可以使用访问对象的属性,foo.property或者foo["property"]属性可以是任何类型,包括函数/方法。

4. 隐藏在您问题中的其他问题

有人可以简要解释一下地图实际上是什么以及它与 Javascript 中的数组不同的重要方式吗?

使用var a = []它创建一个数组,它只包含一个键值对列表,其中所有键都是正数。它还拥有所有Array methods. 数组也是对象。

地图只是一个对象。一个对象只是一袋键值对。您在对象的键下分配一些数据。该数据可以是任何类型。

于 2011-06-22T14:00:36.317 回答
1

对于attr,如果您给出一个对象而不是键值对,它将在每个属性上循环。在 jQuery 的代码中查找attr:,然后你会看到它使用access. 然后查找access:,你会看到有一个类型的检查,key如果它是一个对象,就开始一个循环。

封装在函数中,是为了防止内部的所有代码都被外部访问,从而导致不必要的问题。传递的唯一参数是window允许设置全局变量和访问 DOM。我想这undefined是为了更快地检查这个特殊值。

我有时会阅读 jQuery,但我没有从它开始,也许你应该买一些好书让你首先了解 Javascript 的一些高级功能,然后将你的知识应用到 jQuery 的细节上。

于 2011-06-22T13:54:15.903 回答
1

1 - Yesattr可以接受一个属性名来获取一个值,一个名字和一个值来设置一个值或者一个属性名和值的映射来设置多个属性

2 - 地图基本上是 JavaScript,object例如:

var map = {
    'key1' : 'value1',
    'key2' : 'value2'
};

3 -(function(window, undefined) { /* jQuery */ })(window);是一种叫做 an 的东西,anonymous function因为它没有名字。在这种情况下,它也会立即执行。

一个简单的例子是:

function test(){
    ...
}

test();

//As an anonymous function it would be:

(function(){
    ...

}();

//And it you wanted to pass variables:

function test(abc){
    ...
}

test(abc);

//As an anonymous function it would be:

(function(abc){
    ...

}(abc);

这将使它与加载事件不同,因为它是一个函数而不是一个事件。

4 -window作为变量传递,因为它在 jQuery 内部使用

5 -Objects同样functions,JavaScript 中的所有内容都是object. jQuery 做这样的事情:

var obj = {
    "init" : function(){


    }
}

6 - 是的,您可以使用在 an.上检索 a ,但您也可以使用,例如:valueobject[]

var map = {
    "test" : 1
}


map.test //1
map["test"] //1 

I hope this answers your many questions, let me know if I've missed anything out.

于 2011-06-22T14:08:27.317 回答
0

jQuery 1.6.1

测试是typeof key === "object"

如果这是真的,那么你传递了一个 { .... }

jQuery.fn.extend({
  attr: function( name, value ) {
    return jQuery.access( this, name, value, true, jQuery.attr );
  },

// Mutifunctional method to get and set values to a collection
// The value/s can be optionally by executed if its a function
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;
},
于 2011-06-22T13:57:10.007 回答