Xử lí lỗi document.write can be a form of eval

Một hàm là một tập hợp các cấu trúc lệnh [dòng lệnh] và cuối cùng cho ra một giá trị. Nếu bạn phải thực hiện những tính toán khá dài dòng, phức tạp và phải thực hiện nhiều lần cùng một tính toán như vậy, thay vì mỗi lần tính bạn viết một đống dòng lệnh, bạn chỉ cần viết một lần và đặt tên cho nó là một hàm, rồi sau đó gọi lại hàm này bất cứ lúc nào bạn muốn, không cần phải viết lại một đống dòng lệnh nữa .

Trong một chương trình, người ta thường chia chương trình thành những đoạn nhỏ được gọi là hàm. Việc xây dựng hàm để tránh rườm rà và mất thời gian, mỗi hàm thực hiện một công việc nhất định.

Tiện lợi của hàm trong JavaScript

Có hai ưu điểm chính của hàm JavaScript.

  1. Tái sử dụng code: Chúng ta có thể gọi một hàm nhiều lần để tiết kiệm code.
  2. Giảm code trong chương trình: Hàm làm cho chương trình của chúng tôi nhỏ gọn. Chúng tôi không cần phải viết nhiều dòng mã mỗi lần để thực hiện một tác vụ chung.

Cú pháp khai báo hàm:

function name_of_funtionc[var1, var2, var33,...] {

Khối mã lệnh Javascript  
}

Trong đó:

  • function: là từ khóa của javascript nên bắt buộc phải như vậy
  • name_of_function: là tên của function, thông thường chúng ta tạo những tên có ý nghĩa như find_max, find_min, ...
  • var1, var2 var3, ... là các tham số truyền vào hàm. Ví dụ viết hàm kiểm tra số chẵn hay lẽ thì ta sẽ có một tham số đó là số cần kiểm tra.

Trả về giá trị là một chức năng của hàm, khi thực hiện trả về giá trị hàm sẽ ngừng hoạt động. Để trả về giá trị trong hàm sử dụng khóa return

Ví dụ: hàm kiểm tra chẵn, lẻ sau:

function check_number[number] {

if [number % 2 == 0]{  
    alert[number + ' là số chẵn'];  
}  
else {  
    alert[number + 'Số lẻ'];  
}  
} // Sử dụng hàm kiểm tra cho 5 số check_number[1]; check_number[2]; check_number[3]; check_number[4]; check_number[5];

Xem ví dụ

2. Hàm có return và hàm không có return

Hàm có return là hàm có sử dụng từ khóa return để đặt ở cuối hàm với mục đích trả kết quả về để sử dụng tiếp ở những đoạn code bên ngoài. Ví dụ ta cần viết một hàm tính tổng của hai số a và b thì hàm này phải trả về giá trị là tổng của hai số a, b. Xem ví dụ sau:

// Khai báo hàm function sum[a, b] {

// trả về kết quả là a + b  
return a + b;  
} // Sử dụng var a= 1; var b= 2; // truyền so1 và so2 vào hàm var result= sum[a, b]; document.write[result];

Xem ví dụ

Hàm không có return là hàm không có sử dụng từ khóa return đặt trong hàm. Ví dụ viết chương trình in ra tổng của hai số a và b.

function sum[a, b] {

document.write['Tổng là ' + [a + b]];  
} // Sử dụng var a= 1; var b= 2; // truyền so1 và so2 vào hàm sum[a, b];

Xem ví dụ

Như vậy tùy vào mục đích mà ta dùng có return hay không có return. Nhưng thông thường ta sử dụng return ở những trường hợp cần lấy kết quả đó để xử lý tiếp, như ở ví dụ trên đó là mình lấy kết quả để in thông báo.

3. Giá trị mặc định của tham số

Có một số trường hợp bạn muốn một tham số nào đó có thể được truyền hoặc không cần truyền vào đều được, lúc này chúng ta phải sử dụng nó như một tham số mặc định. Javascript không có cú pháp gán giá trị mặc định như PHP mà thay vào đó chúng ta sử dụng toán tử ||.

Ví dụ: Hàm hiển thị một thông báo.

function showMessage[message] { // Nếu message không được truyền vào hoặc giá trị nó là rỗng // thì sẽ được thay thế bằng giá trị 'Không có tin nhắn' message = message || 'Không có tin nhắn
'; document.write[message]; } // Cách 1: không truyền tham số showMessage[]; // Cách 2: Truyền tham số showMessage['Chào mừng bạn đến với hiệp sĩ it dot com'];

Xem ví dụ

4. Hàm đệ qui trong Javascript

Một hàm được gọi là đệ quy nếu bên trong thân nó có một lời gọi đến chính nó. Nghe có vẻ vô lý nhỉ ? Một hàm làm sao có thể gọi nó mãi được, vì nếu như vậy sẽ sinh ra một vòng lặp vô tận. Nhưng trong thực tế, một hàm đệ quy luôn có điều kiện đừng được gọi là “điểm neo”. Khi đạt tới điểm neo, hàm sẽ không gọi chính nó nữa.

Often these scripts use obsolete methods and techniques, like document.write, that hurt your page load times and user experience.

Just about everyone uses Google Analytics [GA] and if you are like a former client of mine you have GA and 6 other traffic analysis and third-party service scripts injected in each page.

If it is not an analytics script it is an ad script, twitter stream or hosted content service.

Third-party scripts and old libraries are common and the source of many web performance problems.

Many pages use obsolete scripts and libraries. Recent news showed about 95% of web sites load jQuery. But over 90% of those use jQuery version 1.x or 2.x, both long since deprecated.

They can ultimately cost your business money or productivity.

In additional to excessive page load times these scripts often use bad coding techniques. A common issue with code you don't own is the use document.Write to inject markup in your page.

Of course external scripts are not the only offenders, many developers use document.write their own sites.

How document.write Affects Your Page Load

One of the reasons why you should move all script references to the bottom of the page is document.write.

When the browser hits a script block or reference it stops everything till the script is load, parsed and executed.

A big reason why browsers do this is because they assume document.write is used in the script.

When document.write is called the DOM is manipulated in a way that forces the browser to completely reload the markup and re-render it.

This means anything that has been parsed, rendered, etc must be wiped out and replaced from the beginning.

This usually causes a noticeable flash during a page load. Even if you do not see the flash the page you are loading takes longer than it should without the document.write in play.

Because of this you should avoid using document.write in your scripts.

Avoid 3rd party scripts that force you to place script references to them where you want their markup to be rendered.

Handling Dynamically Added Markup

So how should you handle dynamically adding markup to your page?

Instead of using a script that performs a document.write you should use a more conventional strategy.

One technique is to use a document fragment to inject markup. The createDocumentFragment technique is extremely useful when adding dynamic content to a web page.

Instead of requiring an inline script reference require an element target.

In this example I use a DIV that contains an H1 tag just for good measure.

The CSS class is the selector hook, but you could just as easily use an ID. Personally I like CSS classes because that gives me a few more options.


[Dynamic Content]

createFragment is a helper method that can be reused to insert elements or a string of markup in the DOM. It does is create a document fragment containing the desired markup and returns that fragment.

The fragment can then be used in a variety of ways, for the purposes of this demonstration it will be appended as a child element of the target element.

function createFragment[htmlStr] { var frag = document.createDocumentFragment[], temp = document.createElement['div']; temp.innerHTML = htmlStr; while[temp.firstChild] { frag.appendChild[temp.firstChild]; } return frag; } 

Next I get a node [element] reference to the target wrapper element.

Notice I do not use jQuery to select the element, but rather the native querySelector method. This is much faster than the jQuery selector.

var target = document.querySelector[".ajax-target"]; 

If you have multiple targets you will want to use querySelectorAll. Just remember querySelectorAll returns a nodeList you need to loop through where the querySelector returns the first matching element.

The next step is to insert the new document fragment in the target wrapper. The element.appendChild method is used, which accepts a document fragment and inserts it within the element [our wrapper].

The new fragment will be inserted as the last child element, which in this example will be after the H1 element.

To keep the example relatively simple I am passing in a string. This could just as easily be markup returned in an AJAX call or directly loaded HTML. The HTML string will be turned into a fragment to insert.

target.appendChild[createFragment[ "

Hello world!!! I am very dynamic!

" ]]; 

The result is a solution that will dynamically inject markup in the page at the desired location.

Because it targets a specific HTML node[s], the technique eliminates the need to put a script reference in the markup.

Remember, referencing scripts in the middle of the page is a bad practice because it stops the browser from rendering the page.

"document.write can be a form of eval"

One of the fundamentals of using JavaScript is knowing eval is evil.

This is because eval invokes the compiler at run-time. The method takes a string, which is typically more script.

A reason why this is frowned upon is it can be used to inject evil scripts into the page.

document.write can also be used to inject scripts are run-time:

document.write['']; alert[eval[1+2]]; 

This technique is a way bad third party service providers slip bad code into your page.

Another reason to avoid using document.write and third party scripts that do.

Summary

The createDocumentFragment method eliminates the dependency on any third party library [like jQuery] that may or may not be loaded.

In the end the page will load faster, not have a flash or blink during load and the script will not have a dependency on a library that may or may not be loaded. I created a jsFiddle so you can see the code in action, //jsfiddle.net/docluv/vczpT/.

Chủ Đề