01/10/2018, 12:05

! function() trong javascript là gì

for(var i=0; i<10;i++)
{
! function(i){
alert(i);
}(i)
}

chạy sẽ alert từ 1 - 9 vậy dấu ! là sao vậy ạ ?

Zhang Jike viết 14:20 ngày 01/10/2018

Trong javascript thì ! Sẽ biến function được khai báo trở thành biểu thức điều kiện.

let a = 1; // 1
let b = function(i) {
  console.log(i);
}; // [Function]
let c; // undefined
let d = (function(j) {
 console.log(j);
})(3); // Self invoked function always return undefined

console.log(!a); // false
console.log(!b); //false
console.log(!c); // true
console.log(!d); // true

Bản thân ! Không gọi hàm anonymous function được khai báo nhưng khi dùng self invoke function thì do thứ tự ưu tiên cao hơn nên hàm sẽ được gọi đồng thời biểu thức ! function(){}() sẽ return true. Vì self invoke function mặc định return undefined.

Toán tử ! (exclamation mark) sẽ ép các giá trị phía sau thành 1 giá trị boolean rồi return giá trị ngược lại.
Trong javascript thì các giá trị khi ép kiểu sang falsy (return false) bao gồm false null undefined NaN '' "" 0
Khi dùng toán tử ! trước các giá trị này. sẽ thay đổi giá trị của chúng thành truthy (return true)

if (! false)
if (! null)
if (! undefined)
if (! 0)
if (! NaN)
if (! '')
if (! "")

Còn lại là các giá trị truthy đặt toán tử ! trước nó sẽ biến nó thành giá trị falsy.

Mục đích của cách dùng ! trong trường hợp bạn đưa ra. Có lẽ ng dùng chỉ muốn sử dụng cách viết khác như sau:

for(var i = 0; i < 10; i++) {
  (function(i){
    alert(i);
  })(i)
}

Nhưng trong trường hợp này mình không thấy tác dụng của việc làm này lắm. Tại sao không phải là như thế này?

for(var i = 0; i < 10; i++) {
  alert(i);
}

Dùng anonymous trong vòng lặp như thế kia sẽ áp dụng tốt trong trường hợp như sau:

for(var i = 0; i < 5; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000);
}

Trong trường hợp này thì khi dùng khai báo i với var, biến i này sẽ nằm trong function scope, bên ngoài vòng for này. Khi vòng for chạy cực nhanh trong khi setTimeout mất 1 giây delay để thực hiện mỗi lệnh. Nên khi log ra ngoài kết quả sẽ như sau:

5
5
5
5
5

Vậy nên ta sử dụng self invoked function để tạo closure.

for(var i = 0; i < 5; i++) {
  (function(i){
    setTimeout(function() {
      console.log(i);
    }, 1000);
  })(i)
}

Về closure là gì. Bạn nên tìm hiểu về nó. Đây là một từ khóa quan trọng bạn cần biết khi làm việc với Javascript.
Thân.

Duy Hoàng viết 14:16 ngày 01/10/2018

closure

oh thank anh, e hơi hiểu hiểu rồi!!

Zhang Jike viết 14:14 ngày 01/10/2018

Hơi thôi à =)))
Trong js có một số trick. Em có thể cảm thụ dần dần.
Ví dụ như trường hợp ! kia. Hoặc như sau:

let haveMoney = true;

function buyCar() {
  console.log("I will buy a car");
}

// good

if (haveMoney) {
 buyCar();
}

// better

haveMoney && byCar();

Anh nghĩ guide này rất tốt cho người mới học javascript như em. Cố gắng theo ngay tử đầu sẽ rất tốt

GitHub

airbnb/javascript

javascript - JavaScript Style Guide

Duy Hoàng viết 14:06 ngày 01/10/2018

e cảm ơn ạ, cái let nó hay hơn var ở đâu nhỉ anh!!!

Zhang Jike viết 14:06 ngày 01/10/2018

var Trong js là Function scope, còn let là block scope. Vậy là như thế nào?

function increase(element) {
  if (element) {
    var a = element;
    a++;
  };

  console.log(a);
}

increase(2); // log ra 3

còn khi dùng let

function increase(element) {
  if (element) {
    let a = element;
    a++;
  };

  console.log(a);
}

increase(2); // log ra undefined

Vì khai báo biến bằng let hoặc const thì biến đó chỉ nằm trong block scope { ... } còn var thì sẽ làm biến đó nằm trong function scope function() { ... }

let trong ES6 khiến mọi thứ dễ dàng hơn như các ngôn ngữ lập trình khác. Nên mình khuyên bạn. Bỏ hẳn var đi. Thay vào đó dùng let cho biến thay đổi còn const cho biến immutable

Cái thứ nữa mình muốn nói là những vấn đề này cực kì căn bản mà bạn có thể tự search tự tìm hiểu. Trước khi hỏi hãy tìm trước. Khó lắm mới hỏi nhé. Muốn hiểu rõ về JS có 2 nguồn rất đáng học bạn nên nắm chắc:

GitHub

getify/You-Dont-Know-JS

You-Dont-Know-JS - A book series on JavaScript. @YDKJS on twitter.

3.5 giờ đầu của khóa JavaScript: Understanding the Weird Parts. nửa còn lại bạn có thể mua của tác giả trên Udemy. 10 ~ 12$ rất đáng mua.

Bài liên quan
0