+1

MỘT SỐ LỖI KHI SỬ DỤNG STRICT MODE JAVASCRIPT

Trong bài viết trước, tôi có đề cập tới việc sử dụng Strict mode trong việc giảm thiểu những lỗi ngớ ngẩn của lập trình viên khi lập trình JavaScript. Như đã hứa, tôi sẽ đưa ra một số lỗi phổ biến khi sử dụng chế độ này.

1. Sử dụng biến không khai báo

Bình thường khi bạn đưa ra một biến mà không khai báo thì mặc định biến đó sẽ trở thành một thuộc tính của đối tượng global. Đối với browser thì đối tượng global đó chính là window.

x = 10;
console.log(window.x);
// => 10

Ở chế độ strict mode, bạn sẽ bị lỗi x chưa được định nghĩaUncaught ReferenceError: x is not defined

x = 10;
console.log(window.x);
// => Uncaught ReferenceError: x is not defined

2. Gán giá trị cho biến global, thuộc tính chỉ đọc, thuộc tính getter

Ở chế độ bình thường, việc gán giá trị cho biến Global như Infinity, NaN,... hay những thuộc tính chỉ đọc,... sẽ không có thông báo lỗi. Mặc dù việc gán giá trị này là hoàn toàn sai và không có ý nghĩa.

var undefined = 5;
console.log(undefined);
// => undefined

var NaN = 10;
console.log(NaN);
// => NaN

var Infinity = 11;
console.log(Infinity);
// => Infinity 

var obj = {};
Object.defineProperty(obj, 'x', {value: 42, writable: false});
obj.x = 9;
console.log(obj.x);
// => 42 

var obj = {get x(){return 15;}};
obj.x = 10;
console.log(obj.x);
// => 15

var fixed = {};
Object.preventExtensions(fixed);
fixed.x = 10;
console.log(fixed.x);
// => undefined

Khi ở strict mode, bạn chắc chắn sẽ nhận được lỗi như:

  • Uncaught TypeError: Cannot assign to read only property 'undefined' of object '#<Window>'
  • Uncaught TypeError: Cannot assign to read only property 'NaN' of object '#<Window>'
  • Uncaught TypeError: Cannot assign to read only property 'Infinity' of object '#<Window>'
  • Uncaught TypeError: Cannot assign to read only property 'x' of object '#<Object>'
  • Uncaught TypeError: Cannot set property x of #<Object> which has only a getter
  • Uncaught TypeError: Cannot add property x, object is not extensible
var undefined = 5;
console.log(undefined);
// => Uncaught TypeError: Cannot assign to read only property 'undefined' of object '#<Window>'

var NaN = 10;
console.log(NaN);
// => Uncaught TypeError: Cannot assign to read only property 'NaN' of object '#<Window>'

var Infinity = 11;
console.log(Infinity);
// => Uncaught TypeError: Cannot assign to read only property 'Infinity' of object '#<Window>'

var obj = {};
Object.defineProperty(obj, 'x', {value: 42, writable: false});
obj.x = 9;
console.log(obj.x);
// => Uncaught TypeError: Cannot assign to read only property 'x' of object '#<Object>'

var obj = {get x(){return 15;}};
obj.x = 10;
console.log(obj.x);
// => Uncaught TypeError: Cannot set property x of #<Object> which has only a getter

var fixed = {};
Object.preventExtensions(fixed);
fixed.x = 10;
console.log(fixed.x);
// => Uncaught TypeError: Cannot add property x, object is not extensible

3. Xoá thuộc tính của đối tượng Global

Bình thường, bạn sẽ không thể xoá thuộc tính của một đối tượng Global, mặc dù không có thông báo lỗi nào. Khi ở strict mode, bạn sẽ bị lỗi nếu cố gắng xoá một thuộc tính của đối tượng Global: Ví dụ: Uncaught TypeError: Cannot delete property 'prototype' of function Object() { [native code] }

'use strict';
delete Object.prototype;
// Uncaught TypeError: Cannot delete property 'prototype' of function Object() { [native code] }

4. Tên tham số trùng nhau ở khai báo hàm

Strict mode yêu cầu các tham số phải có tên khác nhau. Ngược lại thì bạn sẽ gặp lỗi: Uncaught SyntaxError: Duplicate parameter name not allowed in this context

function sum(a, a, c){
  'use strict'
  return a + b + c;
}
// => Uncaught SyntaxError: Duplicate parameter name not allowed in this context

5. Thêm thuộc tính cho những giá trị nguyên thuỷ

Như các bạn đã biết, giá trị nguyên thuỷ bao gồm: number, string, boolean. Ngược lại, bạn sẽ bị lỗi như:

  • Uncaught TypeError: Cannot create property 'true' on boolean 'false'
  • Uncaught TypeError: Cannot create property 'sailing' on number '14'
  • Uncaught TypeError: Cannot create property 'you' on string 'with'
'use strict';
false.true = false;
// => Uncaught TypeError: Cannot create property 'true' on boolean 'false'

(14).sailing = 'home';
// => Uncaught TypeError: Cannot create property 'sailing' on number '14'

'with'.you = 'far away';
// => Uncaught TypeError: Cannot create property 'you' on string 'with'

6. Xoá một biến thông thường ở Strict mode

Strict mode cấm bạn xoá tên biến. Ngược lại, bạn sẽ bị lỗi là: Uncaught SyntaxError: Delete of an unqualified identifier in strict mode.

'use strict';

var x = 10;
delete x;
// => Uncaught SyntaxError: Delete of an unqualified identifier in strict mode.

7. Đặt tên biến trùng với từ dự trữ

Ngoài từ khoá, JavaScript quy định danh sách những từ dự trữ - những từ sẽ được sử dụng làm từ khoá ở những phiên bản tiếp theo, như: implements, interface, let, package, private, protected, public, static, và yield. Do đó, strict mode nghiêm cấm bạn đặt tên biến số trùng với những từ này. Nếu bạn đặt tên biến trùng với từ dự trữ thì bạn sẽ bị lỗi như sau: <span class="console-message-text">Uncaught <span class="object-value-error source-code">SyntaxError: Unexpected strict mode reserved word</span></span>

'use strict';
var implements = 10;
<span class="console-message-text">// => Uncaught <span class="object-value-error source-code">SyntaxError: Unexpected strict mode reserved word</span></span> 

Kết luận

Trên đây là một số lỗi thường gặp phải khi bạn sử dụng JavaScript ở strict mode. Nói vậy, không có nghĩa là tôi khuyên bạn tránh sử dụng strict mode. Ngược lại, chế độ này giúp bạn dễ dàng phát hiện lỗi. Và đây là sự đảm bảo cho code bạn không bị xung đột với những phiên bản JavaScript mới hơn sau này. Bài viết này sẽ dừng lại ở đây. Xin chào và hẹn gặp lại bạn ở bài viết tiếp theo trong series JavaScript cơ bản.

Tham khảo

Bản gốc: Blog Complete JavaScript

Facebook Fanpage: Complete JavaScript

Facebook Group: Hỏi đáp JavaScript VN


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí