Important : The repo is depreciated, please visit the new tutorial. https://github.com/wangdoc/javascript-tutorial
An open JavaScript tutorial book, focusing on client devices, written in Chinese.
Javascript tutorial book
Home Page: http://javascript.ruanyifeng.com
License: Other
Important : The repo is depreciated, please visit the new tutorial. https://github.com/wangdoc/javascript-tutorial
An open JavaScript tutorial book, focusing on client devices, written in Chinese.
章节4.5运行队列有如下代码
setInterval(function(){console.log(2);},1000);
(function (){ sleeping(3000);})();
其执行结果并不是在sleep后立刻输出三个2, 而是只有 一个 2.
setInterval并不会将同一个任务累积, setInterval会周期性的尝试向队列添加任务, 当检测到任务已经在队列中的时候, setInterval便会跳过, 不会出现一个任务同时多次出现在队列中的情况.
使用以下片段可以更好理解, 等待几秒钟后关闭alert即可看到结果.
var count = 1;
setInterval(function () {
console.log(count++);
}, 1000);
alert('Started!');
个人以为使用时间轴图表的方式可以将其描述的更加明晰. 由于个人表达能力有限, 故未直接修改markdown.
文章中有很多地方没有区分JavaScript
中“S”的大小写,虽然不影响阅读和理解,但感觉不统一,想问作者,有无必要将"Javascript"改成"JavaScript"?
在http://javascript.ruanyifeng.com/grammar/function.html中 1.5 函数名的提升中
我在chorme的命令行中测试的
问题一 =======================
文章原文:
f();
var f = function (){};
// TypeError: undefined is not a function
上面的代码等同于下面的形式。
var f;
f();
f = function () {};
上面代码第二行,调用f的时候,f只是被声明了,还没有被赋值,等于undefined,所以会报错。
我的测试结果
f();
var f = function (){};
上面的代码返回undefined
var f;
f();
f = function () {};
返回:
function () {}
这个结果跟文章中的不同啊?
问题二 =======================
文章原文:
如果同时采用function命令和赋值语句声明同一个函数,最后总是采用赋值语句的定义。
var f = function() {
console.log('1');
}
function f() {
console.log('2');
}
f() // 1
我的测试结果:
VM155:4 Uncaught SyntaxError: Identifier 'f' has already been declared
at Object.InjectedScript._evaluateOn (:878:140)
at Object.InjectedScript._evaluateAndWrap (:811:34)
at Object.InjectedScript.evaluate (:667:21)
老师 http://javascript.ruanyifeng.com/tool/lint.html 这个链接是404
免得大家浪费时间点进去查看 issue 。
发现 Shadow DOM 里面两个示例有问题的样子
https://github.com/ruanyf/jstutorial/blob/gh-pages/htmlapi/webcomponents.md#shadow-dom
var shadowRoot = element.createShadowRoot();
shadowRoot.appendChild(document.body); // 这里写反了
var shadow = document.querySelector('#nameTag').createShadowRoot();
var template = document.querySelector('#nameTagTemplate');
shadow.appendChild(template.content.cloneNode()); // 这里没有传入 true,没克隆子节点
“
如果参数为负数,或大于等于字符串的长度,charAt返回NaN。
“
这里应该返回空字符串
5.8 带符号位的右移运算符(>>>)
...
-4带符号位右移一位,得到2147483646。这主要是因为在JavaScipt内部,-4以10000000000000000000000000000100的32位形式保存,最前面的1表示负值。带符号位右移一位时,这个值变成01000000000000000000000000000010,等于十进制的2147483646。
-4 是以 11111111111111111111111111111100
表示的,用 >>>
右移时,最高位补 0 ,得到 01111111111111111111111111111100
,即 2147483646 。
5.7 右移运算符(>>)
右移运算符表示将一个数的二进制形式向后移动,头部补0。
...
右移运算符移动时不包括符号位,所以-4右移1位,得到的还是负值。
>>
会根据符号位分别在正数和负数最高位补 0 或 1 。
可以用下面这个函数测试,规范说明在:http://www.ecma-international.org/ecma-262/5.1/#sec-11.7.2
function pb(n) {
var s = '';
while (n) {
s = (n & 0x1) + s;
n >>>= 1; // >>= 1 will never end for negative integers
}
return s;
}
原代码
[].concat.call({ a: 1 }, { b: 2 })
// [{ a: 1 }, { b: 2 }]
[].concat.call({ a: 1 }, [2])
// [{a:1}, 2]
// 等同于
[2].concat({a:1})
其中[].concat.call({ a: 1 }, [2])
和[2].concat({a:1})
并不等同。
虽然两者都可以将所需要的数组和对象拼接,从这个目的来说是相同的。但是结果数组上两者顺序是相反的,前者是[{a:1}, 2]
,后者是[2, {a:1}]
,就数组而言这两个数组并不相同,所以严格来说并不等同。
不过并不清楚应该如何纠正这个问题才能使其表述正确
scrollHeight 是可滚动区的总高度
clientHeight 是可见区域的高度
scrollTop 是可见区域顶部距可滚动区顶部的偏移
因此 element.scrollHeight - element.scrollTop === element.clientHeight 是用于判断是否滚动条拉到底的表达式,不是恒成立的。
现在有两个网站,一个是http://a.foo.cn/ ,一个是http://b.foo.cn/。
现在运行了http://a.foo.cn/ ,该网页代码中置document.domain为"foo.cn",结果用XMLHttpRequest访问http://b.foo.cn/ 还是跳到CORS了,为什么?
var a = new Array(undefined,undefined,undefined);
a.forEach(function (x, i) { console.log(i+". "+x) });
// 0. undefined
// 1. undefined
// 2. undefined
for (var i in a){console.log(i)}
// 0
// 1 # this line is missing
// 2
文章连接: http://javascript.ruanyifeng.com/advanced/promise.html
首先Promise
的构造函数如下:
var Promise = function () {
this.state = 'pending';
this.thenables = [];
};
然后您在后面给出的例子是下面这样的:
var preloadImage = function (path) {
return new Promise(function (resolve, reject) {
var image = new Image();
image.onload = resolve;
image.onerror = reject;
image.src = path;
});
};
我不知道您在写(或者说翻译)这篇文章的时候是否有真的运行过你文章的代码(哪怕只运行一次),
您就应该能发现, 这个 preloadImage
在实现上是错误的.
因为 Promise
的构造函数并不接收任何参数,
所以这里传递过去的function
不会被任何人调用,
如果没有地方调用这个方法,那么这个图片浏览器永远不会去加载,也就没有preload
的效果了.
var o = {};
o.valueOf()
// Object --> Object { }
http://javascript.ruanyifeng.com/dom/element.html
(1)getClientRects()
getClientRects方法返回一个类似数组的对象,里面是当前元素在页面上形成的所有矩形。每个矩形都有botto、height、left、right、top和width六个属性,表示它们相对于视口的四个坐标,以及本身的高度和宽度。
botto 应该改为bottom
Github help中看到要建立一个名为username.github.io才能正常显示博客,阮老师建立的是一个名为 jstutorial的项目也可以,这是怎么做到的?
js函数默认值 现在是不是支持
function f(a = 1, b = 1){
alert(b);
alert(a);
}
这种写法了?
阮老师讲函数默认参数的时候 ,用的是这种方法:
function f(a) {
(a !== undefined && a !== null) ? a = a : a = 1;
return a;
}
变成了全局安装express-generator模块才能在命令行中用express xxxx生成项目
圆括号相当于一个匿名函数,并且把最后一个参数的结果返回。
var id=0;
var idplus = (++id, id++);
id === 2; //true
idplus === 1; //true
所以才有闭包的写法
(function(n){
})(1)
第一个()中的function当成函数返回,第二个()中的1则当作参数传入。
网上找不到全面的教程
http://javascript.ruanyifeng.com/grammar/basic.html
1.5注释
此外,由于历史上JavaScript兼容HTML代码的注释,所以<!–和–>也被视为单行注释。
应该是:<!-和-->被视为单行注释
jQuery -> 如何做到 jQuery-free?-> 第一节
“开发者直接使用JavScript标准语法,就能同时在各大浏览器运行,不再需要通过jQuery获取兼容性。”
copy如下代码并且执行:
function f(){return 1;}
f()
(f)
错误时:
TypeError: f(...) is not a function。这是由于“分号的自动添加”。
只要给f()后面追加一个分号就好了
document.getElementByID()
应该是document.getElementById()
http://javascript.ruanyifeng.com/appendix/api.html#toc3
阮老师,你里面写着"2014年12月",让人感觉这个教程很久没更新了 :)
"重要说明:本书正在持续修改之中,大部分章节都没有写完,正式发布还需要一段时间。所有内容随时可能发生变动,目前还不适合转载。(2014年12月)"
下面的例子在Firefox 23 + Firebug 1.12.0中执行的结果和文中所说不一样。
Object.print = function(o){ console.log(o)};
var o = {p:"abc"};
Object.print(o)
输出是:
Object { p="abc"}
Object.prototype.print = function(){ console.log(this)};
var o = {p:"abc"};
o.print()
输出是:
Object { p="abc", print=function()}
undefined
clone了您的tutorial到本地了,怎么生成html本地浏览? 谢谢
requestAnimationFrame是浏览器用于定时循环操作的一个接口,类似于**setTimeout**,主要用途是按帧对网页进行重绘。
应该是 setInterval 更类似.
下面的代码中也应该是用的是 setInterval 而非 setTimeout.
express官方文档中,推荐使用npm start来启动服务器。
node app作为后备使用。
出于同样的原因,对于数组和对象,isNaN也返回true。
isNaN({}) // true
isNaN(Number({})) // true
isNaN(["xzy"]) // true
isNaN(Number(["xzy"])) // true
事实上 用Number转型的时候
Number([])
// 0
Number(["123"])
// 123
Number(["123","213"])
// NaN
有一些特殊数组是可以被转化为number
类型的,isNaN的结果也为false
因此 对于数组和对象
这句话有点不太确切。希望能做出修改
谢谢您的教程
index.md
中,超链接是失效的,不能正确链接到对应的md路径{% highlight javascript %}
和 {% endhighlight %}
语法,在github的md中是无法正确识别的Buffer定义长度大于写入长度,后面填充的值不是固定的,求讲解原理
js 代码
var openRequest = indexedDB.open("test",1);
var db;
openRequest.onupgradeneeded = function(e) {
console.log("Upgrading...");
}
openRequest.onsuccess = function(e) {
console.log("Success!");
db = e.target.result;
db.createObjectStore("firstOS");
}
openRequest.onerror = function(e) {
console.log("Error");
console.dir(e);
}
浏览器端报错信息如下:
(index):22 Uncaught InvalidStateError: Failed to execute 'createObjectStore' on 'IDBDatabase': The database is not running a version change transaction.
希望听到大家对这本教程的反馈,谢谢。
文件:
https://github.com/ruanyf/jstutorial/blob/gh-pages/grammar/array.md
通过函数的call方法,可以用slice方法将类似数组的对象,变成真正的数组。
var arr = Array.prototype.slice.call(arguments);
这里的参数arguments
一开始没太明白,是否改成连接上文例子中的 arrayLike
更容易理解呢?
案例中
var t = performance.timing;
var pageloadtime = t.loadEventStart - t.navigationStart,
var dns = t.domainLookupEnd - t.domainLookupStart,
var tcp = t.connectEnd - t.connectStart,
var ttfb = t.responseStart - t.navigationStart;
第2行到第4行,结束应该是分号。
http://javascript.ruanyifeng.com/grammar/error.html
(6)EvalError
eval函数没有被正确执行时,会抛出EvalError误。
会抛出EvalError错误
引用:http://javascript.ruanyifeng.com/grammar/number.html#toc3
另一方面,64位浮点数的指数部分的长度是11个二进制位,意味着指数部分的最大值是2047(2的11次方减1)。所以,JavaScript能够表示的数值范围为(-22048, 22048),超出这个范围的数无法表示。
这是不正确的说法。
第一,指数是以偏移法表示的,
第二,指数的0值与2047值被用于表示特殊值
第三,表示上限不能忽略前方的有效数字位
真正有意义的表示上下限,是这两个区间[-(253-1)·(2971),-2-1074],[2-1074,(253-1)·(2971)],加上一个点0。
详细解释见我的这篇博文:https://segmentfault.com/a/1190000000407658
如题
感谢@ruanyf无私的付出,你的教程对于我这样的新手很有指导意义。希望能增加测试驱动js开发的章节
http://javascript.ruanyifeng.com/htmlapi/eventsource.html 提到:
浏览器默认的是,如果服务器端三秒内没有发送任何信息,则开始重连。
实际上并不是这样,我理解 规范 里面提到的重新连接的情形包括:(1)HTTP请求以200状态正常结束;(2)网络异常、服务器异常导致的连接失败或中断。而 retry 是指重连前的等待时间。
我找到一个window.performance.getEntriesByType("resource");
这个只能抓到url列表,但是抓不到对应的contents,请问js有这样的接口么,支持这么做么
stdlib/object.md 中说到
但是,出于历史原因,这时依然可以将writable从true变成false,即可以对现有属性重新赋值。
给出的例子是:
var o = { p: 'a' };
Object.seal(o);
o.p = 'b';
o.p // 'b'
这里提到的将 writable 从 true 变成 false ,应该是指 redefine property ,感觉翻译成 重新定义 比 重新赋值 更佳。
且原文附带的示例,是一段对 writable: true 的属性进行重新赋值的代码,属性的 value 是否可变和该对象是否封闭无关。有点混淆理解。
附上一个私以为更为合理的例子:
var o = {p : ""} Object.getOwnPropertyDescriptor(o, 'p') /* { value: '', writable: true, enumerable: true, configurable: true } */ Object.seal(o) Object.getOwnPropertyDescriptor(o, 'p') /* { value: '', writable: true, enumerable: true, configurable: false } */ Object.defineProperty(o, 'p', {writable: false}) Object.getOwnPropertyDescriptor(o, 'p') /* { value: '', writable: false, enumerable: true, configurable: false } */ // node v0.10.32
var i = 1;
var timer = setInterval(function() {
alert(i++);
}, 2000);
我在谷歌浏览器控制台测试了下这段代码,并没有像 文中所说的那样。1. 后面的执行没有立即触发,仍然有2s的等待间隔。2. 第二次,第三次,第四次执行并不会累加起来。
上面代码每隔2000毫秒,就跳出一个alert对话框。如果用户一直不点击“确定”,整个浏览器就处于“堵塞”状态,后面的执行就一直无法触发,将会累积起来。举例来说,第一次跳出alert对话框后,用户过了6000毫秒才点击“确定”,那么第二次、第三次、第四次执行将累积起来,它们之间不会再有等待间隔.
我好像没有找到正则表达式这一块,希望加上这一块
似乎將
Dog.prototype.__proto__ = EventEmitter.prototype;
改成
Dog.prototype= EventEmitter.prototype;
Dog.prototype =new EventEmitter();
都可以跑,但這樣不是應該會蓋掉Dog的prototype,而找不到name屬性報錯嗎
var EventEmitter = require('events').EventEmitter;
function Dog(name) {
this.name = name;
}
Dog.prototype.__proto__ = EventEmitter.prototype;
// 另一种写法
// Dog.prototype = Object.create(EventEmitter.prototype);
var simon = new Dog('simon');
simon.on('bark', function(){
console.log(this.name + ' barked');
});
setInterval(function(){
simon.emit('bark');
}, 500);
vibrate方法还可以接受一个数组作为参数,表示振动的模式。偶数位置的数组成员表示振动的毫秒数,奇数位置的数组成员表示等待的毫秒数。
navigator.vibrate([500, 300, 100]);
上面代码表示,设备先振动500毫秒,然后等待300毫秒,再接着振动500毫秒。
A open JavaScript tutorial book, focusing on client devices, written in Chinese.
=>An open .....
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.