JavaScript

javascript20180801.jpg

JavaScript是一种运行在浏览器中的解释型的编程语言。JavaScript是世界上最流行的脚本语言,因为你在电脑、手机、平板上浏览的所有的网页,以及无数基于HTML5的手机App,交互逻辑都是由JavaScript驱动的。

JavaScript高级程序设计(第3版)

Professional JavaScript for Web

JavaScriptIntroduction.jpg

说到加载图片,我们可以谈些什么

滚屏加载
特殊状态处理
上报监控
居中截取
支持webp

JAVASCRIPT 装载和执行

通常来说,浏览器对于Javascript的运行有两大特性:1)载入后马上执行,2)执行时会阻塞页面后续的内容(包括页面的渲染、其它资源的下载)。于是,如果有多个js文件被引入,那么对于浏览器来说,这些js文件被被串行地载入,并依次执行。

因为javascript可能会来操作HTML文档的DOM树,所以,浏览器一般都不会像并行下载css文件并行下载js文件,因为这是js文件的特殊性造成的。所以,如果你的javascript想操作后面的DOM元素,基本上来说,浏览器都会报错说对象找不到。因为Javascript执行时,后面的HTML被阻塞住了,DOM树时还没有后面的DOM结点。所以程序也就报错了。

1
2
<script type="text/javascript"
src="https://coolshell.cn/asyncjs/alert.js"></script>

基本上来说,head里的script标签会阻塞后续资源的载入以及整个页面的生成。我专门做了一个示例你可以看看:示例一。 注意:我的alert.js中只有一句话:alert(“hello world”) ,这更容易让你看到javascript是怎么阻塞后面的东西的。

所以,你知道为什么有很多网站把javascript放在网页的最后面了,要么就是动用了window.onload或是docmuemt ready之类的事件。

另外,因为绝大多数的Javascript代码并不需要等页面,所以,我们异步载入的功能。那么我们怎么异步载入呢?

document.write方式

于是,你可能以为document.write()这种方式能够解决不阻塞的方式。你当然会觉得,document.write了的 script标签后就可以执行后面的东西去了,这没错。对于在同一个script标签里的Javascript的代码来说,是这样的,但是对于整个页面来说,这个还是会阻塞。 下面是一段测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script type="text/javascript" language="javascript">
function loadjs(script_filename) {
document.write('<' + 'script language="javascript" type="text/javascript"');
document.write(' src="' + script_filename + '">');
document.write('<'+'/script'+'>');
alert("loadjs() exit...");
}

var script = 'https://coolshell.cn/asyncjs/alert.js';

loadjs(script);
alert("loadjs() finished!");
</script>

<script type="text/javascript" language="javascript">
alert("another block");
</script>

你觉得alert的顺序是什么?你可以在不同的浏览器里试一试。这里的想关的测试页面:示例二

script的defer和async属性

IE自从IE6就支持defer标签,如:

1
2
<script defer type="text/javascript" src="./alert.js" >
</script>

对于IE来说,这个标签会让IE并行下载js文件,并且把其执行hold到了整个DOM装载完毕(DOMContentLoaded),多个defer的 script 在执行时也会按照其出现的顺序来运行。最重要的是 script 被加上defer后,其不会阻塞后续DOM的的渲染。但是因为这个defer只是IE专用,所以一般用得比较少。

而我们标准的的HTML5也加入了一个异步载入javascript的属性:async,无论你对它赋什么样的值,只要它出现,它就开始异步加载js文件。但是, async的异步加载会有一个比较严重的问题,那就是它忠实地践行着“载入后马上执行”这条军规,所以,虽然它并不阻塞页面的渲染,但是你也无法控制他执行的次序和时机。你可以看看这个示例去感受一下。

支持 async标签的浏览器是:Firefox3.6+,Chrome 8.0+,Safari 5.0+,IE 10+,Opera还不支持(来自这里)所以这个方法也不是太好。因为并不是所有的浏览器你都能行。

动态创建DOM方式

这种方式可能是用得最多的了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function loadjs(script_filename) {
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', script_filename);
script.setAttribute('id', 'coolshell_script_id');

script_id = document.getElementById('coolshell_script_id');
if(script_id){
document.getElementsByTagName('head')[0].removeChild(script_id);
}
document.getElementsByTagName('head')[0].appendChild(script);
}

var script = 'https://coolshell.cn/asyncjs/alert.js';
loadjs(script);

这个方式几乎成了标准的异步载入js文件的方式,这个方式的演示请参看:示例三。这方式还被玩出了JSONP的东东,也就是我可以为script的src指定某个后台的脚本(如PHP),而这个PHP返回一个javascript函数,其参数是一个json的字符串,返回来调用我们的预先定义好的javascript的函数。你可以看一下这个示例:t.js (这个示例是我之前在微博征集的一个异步ajax调用的小例子)

按需异步载入js

上面那个DOM方式的例子解决了异步载入Javascript的问题,但是没有解决我们想让他按我们指定的时机运行的问题。所以,我们只需要把上面那个DOM方式绑到某个事件上来就可以了。

比如:

绑在window.load事件上——示例四

你一定要比较一下示例四和示例三在执行上有什么不同,我在这两个示例中都专门用了个代码高亮的javascript,看看那个代码高亮的的脚本的执行和我的alert.js的执行的情况,你就知道不同了)

1
window.load = loadjs("https://coolshell.cn/asyncjs/alert.js")

绑在特定的事件上——示例五

1
<p style="cursor: pointer" onclick="LoadJS()">Click to load alert.js </p>

这个示例很简单了。当你点击某个DOM元素,才会真正载入我们的alert.js。

更多

但是,绑定在某个特定事件上这个事似乎又过了一点,因为只有在点击的时候才会去真正的下载js,这又会太慢了了。好了,到这里,要抛出我们的终极问题——我们想要异步地把js文件下载到用户的本地,但是不执行,仅当在我们想要执行的时候去执行。

要是我们有下面这样的方式就好了:

1
2
3
4
5
6
7
var script = document.createElement("script");
script.noexecute = true;
script.src = "alert.js";
document.body.appendChild(script);

//后面我们可以这么干
script.execute();

可惜的是,这只是一个美丽的梦想,今天我们的Javascript还比较原始,这个“JS梦”还没有实现呢。

所以,我们的程序员只能使用hack的方式来搞。

有的程序员使用了非标准的script的type来cache javascript。如:

1
<script type=cache/script src="./alert.js"></script>

因为”cache/script”,这个东西根本就不能被浏览器解析,所以浏览器也就不能把alert.js当javascript去执行,但是他又要去下载js文件,所以就可以搞定了。可惜的是,webkit严格符从了HTML的标准——对于这种不认识的东西,直接删除,什么也不干。于是,我们的梦又破了。

所以,我们需要再hack一下,就像N多年前玩preload图片那样,我们可以动用object标签(也可以动用iframe标签),于是我们有下面这样的代码:

1
2
3
4
5
6
7
8
function cachejs(script_filename){
var cache = document.createElement('object');
cache.data = script_filename;
cache.id = "coolshell_script_cache_id";
cache.width = 0;
cache.height = 0;
document.body.appendChild(cache);
}

然后,我们在的最后调用一下这个函数。请参看一下相关的示例:示例六

在Chrome下按 Ctrl+Shit+I,切换到network页,你就可以看到下载了alert.js但是没有执行,然后我们再用示例五的方式,因为浏览器端有缓存了,不会再从服务器上下载alert.js了。所以,就能保证执行速度了。

关于这种preload这种东西你应该不会陌生了。你还可以使用Ajax的方式,如:

1
2
3
var xhr = new XMLHttpRequest();
xhr.open('GET', 'new.js');
xhr.send('');

到这里我就不再多说了,也不给示例了,大家可以自己试试去。

最后再提两个js,一个是ControlJS,一个叫HeadJS,专门用来做异步load javascript文件的。

好了,这是所有的内容了,希望大家看过后能对Javascript的载入和执行,以及相关的技术有个了解。同时,也希望各前端高手不吝赐教!

统一处理异步的js回调

js编程时经常会用到异步处理,而异步会带了所谓的并发问题。比如,你需要向服务器发出多个ajax请求,然后在返回所有结果后做进一步处理,同时要显示动画。因此我们需要用到以下的方案。

web worker简易入门

js是单线程的语言,由于此特性,我们在处理并发时需要用到一些技巧,如setTimeout(),setInterval(),调用XMLHttpRequest等。
但这里的并发只是非阻塞(参照John Resig的文章How JavaScript Timers Work),真正的多线程编程则需要HTML5的web worker。

JavaScript教程

为什么我们要学JavaScript?尤其是当你已经掌握了某些其他编程语言如Java、C++的情况下。

简单粗暴的回答就是:因为你没有选择。在Web世界里,只有JavaScript能跨平台、跨浏览器驱动网页,与用户交互。

随着HTML5在PC和移动端越来越流行,JavaScript变得更加重要了。并且,新兴的Node.js把JavaScript引入到了服务器端,JavaScript已经变成了全能型选手。

JavaScript严格区分大小写,如果弄错了大小写,程序将报错或者运行不正常。

Number
JavaScript不区分整数和浮点数,统一用Number表示,以下都是合法的Number类型:

1
2
3
4
5
6
123; // 整数123
0.456; // 浮点数0.456
1.2345e3; // 科学计数法表示1.2345x1000,等同于1234.5
-99; // 负数
NaN; // NaN表示Not a Number,当无法计算结果时用NaN表示
Infinity; // Infinity表示无限大,当数值超过了JavaScript的Number所能表示的最大值时,就表示为Infinity

计算机由于使用二进制,所以,有时候用十六进制表示整数比较方便,十六进制用0x前缀和0-9,a-f表示,例如:0xff00,0xa5b4c3d2,等等,它们和十进制表示的数值完全一样。

可视化

Introducing d3.express: the integrated discovery environment.

The purpose of visualization is insight, not pictures.

参考资料

最棒的 JavaScript 学习指南(2018版)

Web前端性能优化——编写高效的JavaScript

Web前端性能优化进阶——完结篇

50 tips of JavaScript,这些坑你都知道吗?

Chart.js

Chart.js 文档

数据可视化—Chart.js使用总结

图表Chart.js入门教程

一个文件夹的自我介绍

Machine Learning in Javascript: Introduction

machinelearning2018050702.jpg

To get good at something, you need to practice!

I love machine learning algorithms. I’ve taught classes and seminars and given talks on ML. The subject is fascinating to me, but like all skills fascination simply isn’t enough. To get good at something, you need to practice!

I also happen to be a PHP and JavaScript developer. I’ve taught classes on both of these as well — but like any decent software engineer I have experience with Ruby, Python, Perl, and C. I just prefer PHP and JS. (Before you flame PHP, I’ll just say that while it has its problems, I like it because it gets stuff done.)

Whenever I say that Tidal Labs’ ML algorithms are in PHP, they look at me funny and ask me how it’s possible. Simple: it’s possible to write ML algorithms in just about any language. Most people just don’t care to learn the fundamentals strongly enough that they can write an algorithm from scratch. Instead, they rely on Python libraries to do the work for them, and end up not truly grasping what’s happening inside the black box. Other people only know ML academically, using Octave or Matlab.

Through this series of articles, I’ll teach you the fundamental machine learning algorithms using Javascript — not Python or Octave — as the example language. Originally I intended to write these articles in a variety of languages (PHP, JS, Perl, C, Ruby), but decided to stick with Javascript for the following reasons:

If you’re a web developer you probably already know JS, regardless of your backend expertise.
Javascript has JSFiddle, a great tool that lets me embed executable Javascript right in my posts (hard to do that with C or Perl!)
Several people asked me to stick to just one language.
While I’ll be writing these articles with Javascript in mind, please re-write the examples in your language of choice as homework! Practice is how you get better, and writing the same algorithm several times in different languages really helps you understand the paradigms better.
It’s possible to get excellent performance out of ML algorithms in languages like PHP and Javascript. I advocate writing ML algorithms in other languages because the practice of writing ML algorithms from scratch helps you learn them fundamentally, and it also helps you unify your backend by not requiring a Python script to do processing in the middle of a PHP application. You can do it in PHP, and cut out the (mental and computational) overhead of using another language.

… well, most of the time. There are some things you really can’t do in PHP or Javascript, but those are the more advanced algorithms that require heavy matrix math. While you can do matrix math in JS, there is a big difference between simply “doing matrix math” and doing it efficiently. The advantage of NumPy or Matlab is not in their ability to do matrix operations, it’s in the fact that they use optimized algorithms to do so — things you wouldn’t be able to do yourself unless you dedicate yourself to learning computational linear algebra. And that’s not my field, so we’ll just stick to the ML that doesn’t require the advanced matrix math. You could try brute-forcing the matrix operations, but you’ll end up with a relatively inefficient system. It’s great for learning, so I’m not discouraging it — I would just be wary of doing that in a production environment.

Keep in mind that most of the algorithms we’ll look at can be solved both with and without matrix math. We’ll use iterative or functional approaches here, but most of these algorithms can be done with linear algebra as well. There’s more than one way to skin a cat! I encourage you to also go and learn (or figure out) the linear algebra approaches, but since that’s not my strong suit I’ll use other approaches.

Here are some of the algorithms I intend to cover. I’ll update this list with links to the relevant articles as they’re published:

k-nearest-neighbor (Introduction)
k-means clustering (Part 1)
Genetic algorithms (Part 1, Part 2)
Naive Bayes classifier (Part 1: Document Classification)
Sentiment Analysis (Part 1)
Full-text Search (Part 1: Relevance Scoring)
Neural network

Happy learning!

Machine Learning in JS: k-nearest-neighbor Introduction

0%