Có một số cách khác nhau để gọi một chức năng mà không có dấu ngoặc đơn.
Giả sử bạn có chức năng này được xác định:
function greet() { console.log('hello'); }Sau đó, ở đây bằng một số cách để gọi new constructor[([arguments])] 1 mà không có dấu ngoặc đơn:
1. Là hàm tạo
Với new constructor[([arguments])] 2, bạn có thể gọi một chức năng mà không có dấu ngoặc đơn:
new greet; // parentheses are optional in this construct.Từ MDN trên bộ lọc new constructor[([arguments])] 2:
Cú pháp
new constructor[([arguments])]
2. Như new constructor[([arguments])] 4 hoặc new constructor[([arguments])] 5 thực hiện
new constructor[([arguments])] 4 và new constructor[([arguments])] 5 là các phương pháp đặc biệt: chúng được gọi là ngầm khi cần chuyển đổi:
var obj = { toString: function() { return 'hello'; } } '' + obj; // concatenation forces cast to string and call to toString.Bạn có thể (AB) sử dụng mẫu này để gọi new constructor[([arguments])] 1 mà không cần dấu ngoặc đơn:
'' + { toString: greet };Hoặc với new constructor[([arguments])] 5:
+{ valueOf: greet };new constructor[([arguments])] 5 và new constructor[([arguments])] 4 trên thực tế được gọi từ phương thức toprimitive (kể từ ES6), và do đó bạn cũng có thể thực hiện phương pháp đó:
+{ [Symbol.toPrimitive]: greet } "" + { [Symbol.toPrimitive]: greet }2.B ghi đè new constructor[([arguments])] 5 trong nguyên mẫu chức năng
Bạn có thể lấy ý tưởng trước đó để ghi đè phương thức new constructor[([arguments])] 5 trên nguyên mẫu var obj = { toString: function() { return 'hello'; } } '' + obj; // concatenation forces cast to string and call to toString. 4:
Function.prototype.valueOf = function() { this.call(this); // Optional improvement: avoid `NaN` issues when used in expressions. return 0; };Một khi bạn đã làm điều đó, bạn có thể viết:
+greet;Và mặc dù có dấu ngoặc đơn liên quan đến dòng, việc gọi kích hoạt thực tế không có dấu ngoặc đơn. Xem thêm về điều này trong blog "Phương thức gọi trong JavaScript, mà không thực sự gọi chúng"
3. Là máy phát điện
Bạn có thể xác định hàm máy phát (với var obj = { toString: function() { return 'hello'; } } '' + obj; // concatenation forces cast to string and call to toString. 5), trả về một trình lặp. Bạn có thể gọi nó bằng cú pháp lan truyền hoặc với cú pháp var obj = { toString: function() { return 'hello'; } } '' + obj; // concatenation forces cast to string and call to toString. 6.
Đầu tiên chúng ta cần một biến thể trình tạo của hàm new constructor[([arguments])] 1 gốc:
function* greet_gen() { console.log('hello'); }Và sau đó chúng tôi gọi nó mà không có dấu ngoặc đơn bằng cách xác định phương thức @@ iterator:
new greet; // parentheses are optional in this construct. 0Thông thường các trình tạo sẽ có từ khóa var obj = { toString: function() { return 'hello'; } } '' + obj; // concatenation forces cast to string and call to toString. 8 ở đâu đó, nhưng không cần thiết để chức năng được gọi.
Câu lệnh cuối cùng gọi hàm, nhưng điều đó cũng có thể được thực hiện với sự phá hủy:
new greet; // parentheses are optional in this construct. 1hoặc cấu trúc var obj = { toString: function() { return 'hello'; } } '' + obj; // concatenation forces cast to string and call to toString. 9, nhưng nó có dấu ngoặc đơn của riêng mình:
new greet; // parentheses are optional in this construct. 2Lưu ý rằng bạn cũng có thể thực hiện các điều trên với chức năng new constructor[([arguments])] 1 ban đầu, nhưng nó sẽ kích hoạt một ngoại lệ trong quy trình, sau khi new constructor[([arguments])] 1 đã được thực thi (thử nghiệm trên FF và Chrome). Bạn có thể quản lý ngoại lệ với khối '' + { toString: greet }; 2.
4. Là getter
@Jehna1 có một câu trả lời đầy đủ về điều này, vì vậy hãy cho anh ta tín dụng. Dưới đây là một cách để gọi một dấu ngoặc đơn hàm trên phạm vi toàn cầu, tránh phương pháp '' + { toString: greet }; 3 không dùng nữa. Nó sử dụng '' + { toString: greet }; 4 thay thế.
Chúng ta cần tạo một biến thể của hàm new constructor[([arguments])] 1 ban đầu cho điều này:
new greet; // parentheses are optional in this construct. 3Và sau đó:
new greet; // parentheses are optional in this construct. 4Thay thế '' + { toString: greet }; 6 bằng bất kỳ đối tượng toàn cầu nào của bạn.
Bạn có thể gọi hàm new constructor[([arguments])] 1 ban đầu mà không để lại dấu vết trên đối tượng toàn cầu như sau:
new greet; // parentheses are optional in this construct. 5Nhưng người ta có thể lập luận rằng chúng ta có dấu ngoặc đơn ở đây (mặc dù chúng không liên quan đến việc gọi thực tế).
5. Chức năng thẻ
Vì ES6, bạn có thể gọi một hàm chuyển nó một mẫu theo nghĩa đen với cú pháp này:
new greet; // parentheses are optional in this construct. 6Xem "Tagged Memlate Lingerals".
6. Là người xử lý proxy
Kể từ ES6, bạn có thể xác định proxy:
new greet; // parentheses are optional in this construct. 7Và sau đó đọc bất kỳ giá trị tài sản nào sẽ được gọi new constructor[([arguments])] 1:
new greet; // parentheses are optional in this construct. 8Có nhiều biến thể của điều này. Một ví dụ nữa:
new greet; // parentheses are optional in this construct. 97. Như trình kiểm tra ví dụ
Toán tử '' + { toString: greet }; 9 thực thi phương thức +{ valueOf: greet }; 0 trên toán hạng thứ hai, khi được xác định:
new constructor[([arguments])] 0