Mengapa JSHINT mengeluh bahwa ini adalah pelanggaran ketat?

98

Saya pikir ini mungkin duplikat dari Pelanggaran Ketat menggunakan kata kunci ini dan pola modul terbuka

Saya memiliki kode ini:

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);
}

Dan JSHINT (JSLINT) mengeluh. Tercantum "Pelanggaran ketat". untuk garis yang disorot:

masukkan deskripsi gambar di sini

Apakah penggunaan saya atas Function.call()dan kemudian mereferensikan instance, entah bagaimana tidak pantas?

Apakah ini dianggap gaya yang buruk?

Cheeso
sumber
Apakah hanya tertulis "Pelanggaran ketat", tanpa pesan kesalahan mendetail?
stivlo
Saya tidak dapat mereproduksi masalah, saya menjalankan kode melalui JSHint dan JSLint dan sepertinya tidak mengeluh tentang apa pun.
Peter Olson
54
Perhatikan bahwa ini akan jauh lebih mudah untuk didiagnosis jika Anda tidak mencoba menjejalkannya menjadi satu kalimat yang konyol: P.
Domenic
1
Saya telah melihat ini di pertanyaan lain (tidak dapat menemukannya sekarang). Ini ada hubungannya dengan penggunaan this. Saya tidak tahu mengapa JSLint akan menyebutnya Pelanggaran Ketat, tetapi saya tahu bahwa jika Anda tidak menentukan thisnilai suatu fungsi, itu akan berada undefineddalam mode ketat. Jelas Anda sedang mendefinisikan this, jadi itu seharusnya tidak menjadi masalah.
pengguna113716
2
Anda dapat mengabaikan kemungkinan pelanggaran ketat ini dengan "-W040":truedi config json, tetapi karena json tidak memiliki komentar, Anda tidak dapat memberi tahu siapa pun mengapa itu ada.
kojiro

Jawaban:

124

JSHint mengatakan "Kemungkinan pelanggaran ketat" karena Anda menggunakan thissesuatu di dalam yang, sejauh yang diketahui, bukanlah sebuah metode.

Dalam mode non-ketat, panggilan gotoPage(5)akan mengikat thisobjek global ( windowdi browser). Dalam mode ketat, thisakan undefined, dan Anda akan mendapat masalah.

Agaknya, Anda bermaksud memanggil fungsi ini dengan thiskonteks terikat , misalnya gotoPage.bind(myObj)(5)atau gotoPage.call(myObj, 5). Jika demikian, Anda dapat mengabaikan JSHint, karena Anda tidak akan menghasilkan kesalahan apa pun. Tetapi, ia memberi tahu Anda bahwa kode Anda tidak jelas bagi siapa pun yang membacanya, karena menggunakan thisdi dalam sesuatu yang jelas bukan merupakan metode cukup membingungkan. Akan lebih baik untuk meneruskan objek sebagai parameter:

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);
}
Domenik
sumber
12
Meski begitu, saya pikir mereka agak menyesatkan dalam deskripsi. Bahkan jika thisakhirnya menjadi undefined, maka masalah sebenarnya bukan hanya pelanggaran mode ketat . Mereka akan lebih baik memberikan peringatan yang mengatakan bahwa thismungkin undefinedketika dalam "mode ketat", mengarah ke TypeError(atau sesuatu).
pengguna113716
11
@ ripper234 memang, itulah mengapa saya selalu menggunakan event.currentTargetsebagai gantinya this.
Domenic
4
Perintah konfigurasi apa yang dapat saya tambahkan .jshintrcuntuk menonaktifkan pemeriksaan ini?
callum
7
@callum "validthis": true
Brett
18
Gunakan /* jshint validthis: true */jika Anda hanya memiliki pasangan dan tidak ingin berubah untuk setiap kasus.
knownasilya
93

Saya menerima pesan ini untuk fungsi yang tidak dimulai dengan huruf kapital.

"use strict";

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


// ---> just fine (note the capital S in Something)
function Something() {
    this.test = "";
}
amenthes
sumber
28
Saya akan mencatat bahwa jshint mungkin berasumsi, karena konvensi, itu Somethingadalah konstruktor karena kapital S, dan karenanya harus dipanggil menggunakan new. Melakukannya berarti thismenjadi objek baru berdasarkan pada `Something.prototype '. Kemungkinan besar karena asumsi itu tidak memunculkan peringatan kemungkinan pelanggaran ketat.
Andy Merts
4
Saya mengalami kesalahan ini pada penyedia AngularJS, oleh karena itu nama metode huruf besar-unta diharapkan dan saya memiliki huruf kecil-unta. Tetap.
Deminetix
Saya memiliki masalah serupa, ketika memiliki nama fungsi hanya huruf kecil, mengganti nama menggunakan Capital.
GibboK
Jangan gunakan huruf kapital pertama karena itu juga konstruktor, Anda akan menghadapi masalah lain. alih-alih, Anda dapat menggunakan: var fnAbc = function () {this.test = ""}
Hieu Tran AGI
Huruf kapital tidak mengubah apa pun tentang cara kerja bagian dalam fungsi. Ini hanyalah sesuatu yang biasanya dilakukan pemrogram dengan cara ini untuk menyampaikan makna. Dengan kata lain: ini bukan masalah teknologi, tapi masalah komunikasi antar homans.
amenthes
9

Jika Anda mendeklarasikan fungsi sebagai variabel daripada menggunakan deklarasi fungsi standar, jshint tidak akan menandai ini sebagai pelanggaran ketat. Jadi, Anda dapat melakukan hal berikut -

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);
};
asulaiman
sumber
0

Jika Anda mencoba mengimplementasikan suatu metode, Anda mungkin ingin menetapkan ke prototipe sebagai gantinya:

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

JSHint tidak akan memperingatkan ketika fungsi sedang ditetapkan.

Flimm
sumber
Masih belum cukup bagus. ClassName.prototype.myMethod = myMethod;, lalu tentukan metode di bawah. Anda masih mendapatkan kesalahan meskipun myMethod terikat dengan benar.
Jefftopia