01/10/2018, 17:10

Hỏi về javascript tham số (i, origValue)

Em đang học jquery và thấy có đoạn code hơi khó hiểu 1 chút(em copy tren w3schools), vấn đề ở chỗ hai parametter là i, origValue lấy giá trị ở đâu ra để có kết quả như vậy ạ. vì trước khi truyền 2 tham số vào thì chưa thấy khởi tạo giá trị. bro nào thông não giùm em vs ạ.

<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
    $("button").click(function(){
        $("#w3s").attr("href", function(i, origValue){
            return origValue + "/jquery/"; 
        });
    }); 
});
</script>
</head>
<body>

<p><a href="https://www.w3schools.com" id="w3s">W3Schools.com</a></p>

<button>Change href Value</button>

<p>Mouse over the link (or click on it) to see that the value of the href attribute has changed.</p>

</body>
</html>

Link: https://www.w3schools.com/jquery/tryit.asp?filename=tryjquery_dom_attr_callback

EternalRerosu viết 19:20 ngày 01/10/2018

origValue chính là giá trị hiện tại của “href” trong element có id “#w3s
còn i là index

Ngoclong Pham viết 19:11 ngày 01/10/2018

Dạ, cái này thì em hiểu. nhưng tham số truyền vào đó ở đâu ra hả anh, hay nó là mặc định như vậy. bởi vì nó chưa hề được khởi tạo giá trị thì làm sao nó có giá trị được ạ

EternalRerosu viết 19:17 ngày 01/10/2018

vào đọc doc của jquery đi : http://api.jquery.com/attr/#attr-attributeName-function

Ngoclong Pham viết 19:23 ngày 01/10/2018

em đọc rồi, mà anh không hiểu câu hỏi của em rồi.

Ngoclong Pham viết 19:26 ngày 01/10/2018

vào đọc doc của jquery đi : http://api.jquery.com/attr/#attr-attributeName-function

Ý của em là cái function callback đấy nhập vào 2 tham số và return. nhưng em không hiểu là 2 tham số ấy được định nghĩa ở đâu. trong code không hề có khởi tạo giá trị cho nó

Sáng Béo viết 19:20 ngày 01/10/2018

cái hàm này:

function(i, origValue){
  return origValue + "/jquery/"; 
}

chính là hàm do bạn định nghĩa, tên tham số sử dụng trong hàm đó là do bạn tự đặt ra. hàm attr kia sẽ gọi đến hàm này của bạn và truyền vào các đối số vào.
bạn có thể tìm hiểu thêm về callback nhé, cũng kiểu bạn sẽ định nghĩa hàm truyền vào cho function khác gọi đến.

Hung viết 19:21 ngày 01/10/2018

Bạn trên dẫn link API chi tiết rồi mà bạn không hiểu, thì mình chuyển sang đọc source code cho tiện.


Hàm toType(obj) có thể xem là kết quả của typeof obj. Với obj là string thì toType(obj) trả về chuỗi “string”

function toType(obj) {
  if (obj == null)
    return obj + '';
  
  return (
    typeof obj === 'object' ||
    typeof obj === 'function' ?
      class2type[toString.call(obj)] || "object" :
      typeof obj;
  );
}

Hàm isFunction() kiểm tra 1 object có phải là function. Nghĩ đơn giản vậy là được rồi.

var isFunction = function isFunction(obj) {
  return typeof obj === "function" && typeof obj.nodeType !== "number";
};

Code sau khi đơn giản thế này, trích từ code gốc của jQuery. Mình loại mấy trường hợp tính toán và gọi hàm linh tinh thì rút gọn được vậy.

jQuery.fn.extend({
  attr: function (name, value) {
    if (toType(name) === 'object') {
      // do other stuff
    }

    if (!isFunction(value)) {
      // another stuff
    }


    for (var i = 0; i < this.length; i++) {
      var elem = this[i];
      if (typeof elem.getAttribute === 'undefined') {
        jQuery.fn.prop.call(elem, name, value);
        break;
      }

      var originValue = elem.getAttribute(name);
      var newValue = value.call(elem, i, originValue);
      elem.setAttribute(name, newValue);
    }
  }
});

Trong jQuery.fn.extend có nhận object, object có property là attr kiểu function object. Khi gọi $('#w3s').attr() thì gọi tới function của attr.

  • this$('#w3s')
  • namehref, kiểu string
  • valuefunction () {...}

Trình tự như sau:

  • toType('href') trả về “string”, block trong if không thực hiện.

  • value là function object, isFunction(value) trả về true, block trong if không thực hiện.

  • this là kết quả sau khi thực thi $('w3s'), kiểu array-like object, có property length và các property có property descriptor Enumerable là true, dạng “0”, “1”, “2”

  • Dùng for để lấy từng phần tử trong array-like object this, gán vào elem.

  • Kiểm tra elem có property getAttribute hay không, nếu không sử dụng jQuery function prop thay thế. Giả sử elemgetAttribute, typeof elem.getAttribute === 'undefined' trả về false. Block trong if không thực hiện.

  • Lấy giá trị attribute ‘href’ thông qua getAttribute, gán vào biến originValue.

  • value là function object, gọi value() với các tham số i là index của for, originValue là giá trị vừa lấy, giá trị trả về gán vào newValue (Trả lời câu hỏi ban đầu của thớt luôn, ioriginValue gọi ở đâu?)

  • Gán giá trị mới newValue vào ‘href’ của elem.

Ngoclong Pham viết 19:19 ngày 01/10/2018

Thanks anh rất nhiều
Mãi mới có người support :)).
Tại em mới chuyển ngành chẳng có nền tảng mà nhảy qua học java-core, mãi mới sang được phần này, đến đoạn truyền tham số mà không thấy nó được khởi tạo nên hơi thắc mắc

Sáng Béo viết 19:22 ngày 01/10/2018

@Ngoclong_Pham quan trọng là bạn phải để ý chỗ đấy là định nghĩa hàm chứ không phải là gọi hàm.


@hungsteve a có thể chỉ cho e cách xem source các hàm của jquery ở đâu được không ạ?
nhiều lúc e muốn xem nhưng k tìm thấy

Hung viết 19:20 ngày 01/10/2018

Mình chỉ mò code của jQuery, rồi try hard thủ công thôi.

Bước đầu mở code của nó Download the uncompressed, development jQuery 3.3.1, nhấn Cmd + F (Ctrl + F) để tìm với từ khoá attr, mò mò mò, ra 2 hàm jQuery.attrjQuery.fn.attr. Sau đó debug thử, đặt breakpoint xem nó vô attr nào? Sau đó lại áp dụng một cách thủ công các biến vào, rồi mò tiếp

Đoạn code trên chỉ chạy được với name là string và value là function thôi, mình cũng mò tới đó. ngoài ra còn có nhiều trường hợp nữa: value kiểu primitive type, object thuần (không phải function), href là DOM hay jQuery element. Mấy trường hợp khác mình chưa mò.

Sáng Béo viết 19:10 ngày 01/10/2018

à, ra là ở bản uncompressed.
e toàn down bản .min nên không mò được source của nó.
cảm ơn a nhé

Bài liên quan
0