Tại sao JSHINT lại phàn nàn rằng đây là một vi phạm nghiêm trọng?


98

Tôi nghĩ rằng đây có thể là một bản sao của Vi phạm nghiêm trọng bằng cách sử dụng từ khóa này và tiết lộ mẫu mô-đun

Tôi có mã này:

function gotoPage(s){
    if(s<=this.d&&s>0){this.g=s; this.page((s-1)*this.p.size);}
}

function pageChange(event, sorter) {
    var dd = event.currentTarget;
    gotoPage.call(sorter, dd[dd.selectedIndex].value);
}

Và JSHINT (JSLINT) đang phàn nàn. Nó nói "Vi phạm nghiêm trọng." cho dòng được đánh dấu:

nhập mô tả hình ảnh ở đây

Việc tôi sử dụng Function.call()và sau đó tham chiếu phiên bản, bằng cách nào đó không phù hợp?

Đây có được coi là phong cách xấu không?


Nó chỉ nói "Vi phạm nghiêm trọng", mà không có bất kỳ thông báo lỗi chi tiết nào?
stivlo

Tôi không thể tái tạo sự cố, tôi đã chạy mã thông qua JSHint và JSLint và nó dường như không phàn nàn về bất cứ điều gì.
Peter Olson

54
Lưu ý rằng điều này sẽ dễ dàng chẩn đoán hơn nhiều nếu bạn không cố gắng nhồi nhét nó vào một lớp lót vô lý: P.
Domenic

1
Tôi đã thấy điều này trong một câu hỏi khác (không thể tìm thấy nó ngay bây giờ). Nó có liên quan đến việc sử dụng this. Tôi không biết tại sao JSLint lại gọi nó là Vi phạm nghiêm ngặt, nhưng tôi biết rằng nếu bạn không xác định thisgiá trị của một hàm, nó sẽ undefinedở chế độ nghiêm ngặt. Rõ ràng là bạn đang xác định this, vì vậy nó không phải là một vấn đề.
dùng113716

2
Bạn có thể bỏ qua những vi phạm nghiêm trọng có thể"-W040":truetrong config json, nhưng vì json không có nhận xét, bạn không thể nói cho ai biết lý do tại sao nó ở đó.
kojiro

Câu trả lời:


124

JSHint nói rằng "Có thể có vi phạm nghiêm trọng" bởi vì bạn đang sử dụng thisbên trong một thứ gì đó, theo như nó có thể nói, không phải là một phương thức.

Ở chế độ không nghiêm ngặt, việc gọi gotoPage(5)sẽ liên kết thisvới đối tượng chung ( windowtrong trình duyệt). Ở chế độ nghiêm ngặt, thissẽ có undefined, và bạn sẽ gặp rắc rối.

Có lẽ, bạn muốn gọi hàm này với một thisngữ cảnh ràng buộc , ví dụ: gotoPage.bind(myObj)(5)hoặc gotoPage.call(myObj, 5). Nếu vậy, bạn có thể bỏ qua JSHint, vì bạn sẽ không tạo ra bất kỳ lỗi nào. Tuy nhiên, nó cho bạn biết rằng mã của bạn không rõ ràng đối với bất kỳ ai đọc nó, bởi vì việc sử dụng thisbên trong một thứ gì đó không rõ ràng là một phương pháp khá khó hiểu. Sẽ tốt hơn nếu chỉ chuyển đối tượng dưới dạng tham số:

function gotoPage(sorter, s) {
    if (s <= sorter.d && s > 0) {
        sorter.g = s;

        sorter.page((s - 1) * sorter.p.size);
    }
}

function pageChange(event, sorter) {
    var dd = event.currentTarget;
    gotoPage(sorter, dd[dd.selectedIndex].value);
}

12
Mặc dù vậy, tôi nghĩ rằng chúng hơi sai lệch trong mô tả. Ngay cả khi thiscuối cùng xảy ra undefined, thì vấn đề thực tế không chỉ là vi phạm chế độ nghiêm ngặt . Họ sẽ làm tốt hơn khi đưa ra cảnh báo rằng thiscó thể xảy ra undefinedkhi ở "chế độ nghiêm ngặt", dẫn đến một TypeError(hoặc điều gì đó).
dùng113716

11
@ ripper234 thực sự, đó là lý do tại sao tôi luôn sử dụng event.currentTargetthay vì this.
Domenic

4
Tôi có thể thêm chỉ thị cấu hình nào .jshintrcđể tắt kiểm tra này?
callum

7
@callum "validthis": true
Brett

18
Sử dụng /* jshint validthis: true */nếu bạn chỉ có một đôi và không muốn thay đổi cho mọi trường hợp.
knownasilya

93

Tôi đã nhận được thông báo này cho một hàm không bắt đầu bằng chữ hoa.

"use strict";

// ---> strict violation
function something() {
    this.test = "";
}


// ---> just fine (note the capital S in Something)
function Something() {
    this.test = "";
}

28
Tôi xin lưu ý rằng jshint có thể giả định, theo quy ước, đó Somethinglà một hàm tạo do chữ S viết hoa, và vì vậy nên được gọi bằng cách sử dụng new. Làm như vậy xác định thislà một đối tượng mới dựa trên `` Something.prototype ''. Rất có thể do giả định rằng nó không đưa ra cảnh báo vi phạm nghiêm ngặt có thể xảy ra.
Andy Merts

4
Tôi đã gặp lỗi này trên một nhà cung cấp AngularJS, do đó, các tên phương thức viết hoa trên lạc đà được mong đợi và tôi đã gặp phải trường hợp lạc đà thấp hơn. Đã sửa.
Deminetix

Tôi đã gặp vấn đề tương tự, khi có tên hàm chỉ là chữ thường, đổi tên bằng cách sử dụng Capital.
GibboK

Đừng sử dụng chữ cái đầu tiên viết hoa vì nó cũng là một hàm tạo, bạn sẽ phải đối mặt với một vấn đề khác. thay vào đó, bạn có thể sử dụng: var fnAbc = function () {this.test = ""}
Hieu Tran AGI

Chữ in hoa không thay đổi bất cứ điều gì về hoạt động bên trong của hàm. Nó chỉ là thứ mà các lập trình viên thường làm theo cách này để truyền đạt ý nghĩa. Nói cách khác: đây không phải là vấn đề công nghệ, mà là do giao tiếp giữa những người đồng tính.
amenthes

9

Nếu bạn khai báo hàm dưới dạng một biến thay vì sử dụng khai báo hàm tiêu chuẩn, jshint sẽ không gắn cờ điều này là vi phạm nghiêm trọng. Vì vậy, bạn có thể làm như sau:

var gotoPage = function (s){
    if(s<=this.d&&s>0){this.g=s; this.page((s-1)*this.p.size);}
};


var pageChange = function (event, sorter) {
    var dd = event.currentTarget;
    gotoPage.call(sorter, dd[dd.selectedIndex].value);
};

0

Nếu bạn đang cố gắng triển khai một phương pháp, bạn có thể muốn gán cho nguyên mẫu thay thế:

ExampleClassName.protytpe.gotoPage = function gotoPage(s){
  // code using this
};

JSHint sẽ không cảnh báo khi chức năng đang được chỉ định.


Vẫn chưa đủ tốt. ClassName.prototype.myMethod = myMethod;, sau đó xác định phương thức bên dưới. Bạn vẫn gặp lỗi mặc dù myMethod được ràng buộc chính xác.
Jefftopia
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.