เหตุใด JSHINT จึงบ่นว่านี่เป็นการละเมิดอย่างเข้มงวด


98

ฉันคิดว่านี่อาจซ้ำกับการละเมิดอย่างเข้มงวดโดยใช้คำหลักนี้และรูปแบบโมดูลที่เปิดเผย

ฉันมีรหัสนี้:

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

และ JSHINT (JSLINT) กำลังบ่น มีข้อความว่า "ละเมิดอย่างเข้มงวด" สำหรับบรรทัดที่ไฮไลต์:

ป้อนคำอธิบายภาพที่นี่

การใช้งานFunction.call()และอ้างถึงอินสแตนซ์ของฉันไม่เหมาะสมหรือไม่

ถือว่าเป็นลักษณะที่ไม่ดีหรือไม่?


มีเพียงคำว่า "ละเมิดอย่างเข้มงวด" โดยไม่มีข้อความแสดงข้อผิดพลาดโดยละเอียดหรือไม่
stivlo

ฉันไม่สามารถสร้างปัญหาซ้ำได้ฉันรันโค้ดผ่าน JSHint และ JSLint และดูเหมือนจะไม่บ่นอะไร
Peter Olson

54
โปรดทราบว่าสิ่งนี้จะง่ายกว่ามากในการวินิจฉัยหากคุณไม่ได้พยายามยัดมันลงในซับเดียวที่ไร้สาระ: P.
Domenic

1
ฉันเคยเห็นสิ่งนี้ในคำถามอื่น (หาไม่ได้ในขณะนี้) จะต้องทำอย่างไรกับการใช้this. ฉันไม่รู้ว่าทำไม JSLint ถึงเรียกมันว่าการละเมิดอย่างเข้มงวด แต่ฉันรู้ว่าถ้าคุณไม่กำหนดthisค่าของฟังก์ชันฟังก์ชันนั้นจะอยู่undefinedในโหมดเข้มงวด ชัดเจนว่าคุณกำลังกำหนดthisดังนั้นจึงไม่ควรเป็นปัญหา
user113716

2
คุณสามารถละเว้นเหล่านี้ละเมิดเข้มงวดเป็นไปได้ที่มี"-W040":trueอยู่ในการกำหนดค่า JSON แต่เนื่องจาก JSON ไม่ได้มีความคิดเห็นที่คุณไม่สามารถบอกใครว่าทำไมมันมี
kojiro

คำตอบ:


124

JSHint ระบุว่า "อาจมีการละเมิดอย่างเข้มงวด" เนื่องจากคุณกำลังใช้thisสิ่งที่อยู่ภายในสิ่งที่สามารถบอกได้ว่าไม่ใช่วิธีการ

ในโหมดที่ไม่เข้มงวดการโทรgotoPage(5)จะผูกthisกับวัตถุส่วนกลาง ( windowในเบราว์เซอร์) ในโหมดเข้มงวดthisจะเป็นundefinedและคุณจะมีปัญหา

สมมุติคุณหมายถึงจะเรียกฟังก์ชั่นนี้ด้วยผูกพันthisบริบทเช่นหรือgotoPage.bind(myObj)(5) gotoPage.call(myObj, 5)ในกรณีนี้คุณสามารถเพิกเฉยต่อ JSHint ได้เนื่องจากคุณจะไม่สร้างข้อผิดพลาดใด ๆ แต่มันเป็นการบอกคุณว่ารหัสของคุณไม่ชัดเจนสำหรับทุกคนที่อ่านมันเนื่องจากการใช้thisสิ่งที่ไม่ใช่วิธีการอย่างชัดเจนจึงค่อนข้างสับสน มันจะดีกว่าถ้าส่งผ่านวัตถุเป็นพารามิเตอร์:

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
ถึงอย่างนั้นฉันคิดว่าคำอธิบายเหล่านี้ทำให้เข้าใจผิดเล็กน้อย แม้ว่าthisจะจบลงundefinedแต่ปัญหาที่เกิดขึ้นจริงไม่ใช่แค่การละเมิดโหมดที่เข้มงวดเท่านั้น พวกเขาจะทำได้ดีกว่าที่จะให้คำเตือนโดยบอกว่าthisอาจอยู่undefinedใน "โหมดเข้มงวด" ซึ่งนำไปสู่TypeError(หรือบางอย่าง)
user113716

11
@ ripper234 นั่นเป็นเหตุผลว่าทำไมฉันจึงใช้event.currentTargetแทนthis.
Domenic

4
ฉันสามารถเพิ่มคำสั่งการกำหนดค่าใด.jshintrcเพื่อปิดใช้งานการตรวจสอบนี้
callum

7
@callum "validthis": true
Brett

18
ใช้ใน/* jshint validthis: true */กรณีที่คุณมีคู่และไม่ต้องการเปลี่ยนสำหรับทุกกรณี
knownasilya

93

ฉันมีข้อความนี้สำหรับฟังก์ชันที่ไม่ได้ขึ้นต้นด้วยอักษรตัวใหญ่

"use strict";

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


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

28
ฉันจะทราบ jshint ที่น่าจะเป็นสมมติว่าเนื่องจากการประชุมที่Somethingเป็นตัวสร้างเนื่องจากทุน S และอื่น ๆ newควรจะเรียกใช้ เพื่อกำหนดthisให้เป็น object ใหม่ตาม `Something.prototype ' เป็นไปได้มากที่สุดเนื่องจากสมมติฐานดังกล่าวไม่ได้แจ้งเตือนการละเมิดที่เข้มงวด
Andy Merts

4
ฉันมีข้อผิดพลาดนี้กับผู้ให้บริการ AngularJS ดังนั้นจึงคาดว่าจะมีชื่อเมธอดกรณีอูฐตัวบนและฉันมีตัวพิมพ์เล็กอูฐ แก้ไขแล้ว.
Deminetix

ฉันมีปัญหาที่คล้ายกันเมื่อมีชื่อฟังก์ชันเพียงตัวพิมพ์เล็กการเปลี่ยนชื่อโดยใช้ Capital
GibboK

อย่าใช้อักษรตัวพิมพ์ใหญ่เพราะเป็นตัวสร้างคุณจะประสบปัญหาอื่น แทนที่จะใช้: var fnAbc = function () {this.test = ""}
Hieu Tran AGI

อักษรตัวใหญ่จะไม่เปลี่ยนแปลงอะไรเกี่ยวกับการทำงานภายในของฟังก์ชัน เป็นเพียงสิ่งที่โปรแกรมเมอร์มักใช้วิธีนี้เพื่อสื่อความหมาย กล่าวอีกนัยหนึ่ง: นี่ไม่ใช่ปัญหาทางเทคโนโลยี แต่เป็นการสื่อสารระหว่างโฮแมน
amenthes

9

หากคุณประกาศฟังก์ชันเป็นตัวแปรแทนที่จะใช้การประกาศฟังก์ชันมาตรฐาน jshint จะไม่ตั้งค่าสถานะว่าเป็นการละเมิดที่เข้มงวด ดังนั้นคุณสามารถทำสิ่งต่อไปนี้ -

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

หากคุณกำลังพยายามใช้วิธีการคุณอาจต้องการกำหนดให้กับต้นแบบแทน:

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

JSHint จะไม่เตือนเมื่อมีการกำหนดฟังก์ชัน


ยังดีไม่พอ. ClassName.prototype.myMethod = myMethod;จากนั้นกำหนดวิธีการด้านล่าง คุณยังคงได้รับข้อผิดพลาดแม้ว่า myMethod จะถูกผูกไว้อย่างถูกต้อง
Jefftopia
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.