一些javascript的知识点总结

总结一些前端的知识点 (一)【转载】

林东洲8 天前

想学习前端或编程知识欢迎关注专栏:敲代码,学编程 - 知乎专栏
一、W3C 标准盒模型和 IE 盒模型区别:

  1. W3C 标准盒模型:


    盒子的高宽是由盒子的内容区仅由 width, height 决定的,不包含边框,内外边距。

  2. IE 盒模型:


    在 IE 盒模型中,盒子宽高不仅包含了元素的宽高,而且包含了元素的边框以及内边距。
    所以在同样的设置下,IE 下的元素会看起来相对于标准盒子来的小,如果你想要标准盒子变为像 IE 盒模型,可以对元素样式进行设置:
    .item { box-sizing: border-box; //IE 盒模型效果 box-sizing: content-box; //默认值,标准盒模型效果}

二、querySelectorAll 与 getElementsBy 系列的区别:
根据该问题下的答案 querySelectorAll 方法相比 getElementsBy 系列方法有什么区别?,我简单地总结一下:
querySelectorAll 属于 W3C 中 Selectors API 规范, 而 getElementsBy 系列则属于 W3C DOM 规范。
querySelectorAll 方法接受参数是 CSS 选择符,当传入的是不符合 CSS 选择符规范时会抛出异常,而 getElementsBy 系列则接受的参数是单一的 className,tagName 等等。
从返回值角度来看,querySelectorAll 返回的是不变的结点列表,而 getElementsBy 系列返回的是动态的结点列表。

// Demo 1var ul = document.querySelectorAll('ul')[0], lis = ul.querySelectorAll("li");for(var i = 0; i < lis.length ; i++){ ul.appendChild(document.createElement("li"));}// Demo 2var ul = document.getElementsByTagName('ul')[0], lis = ul.getElementsByTagName("li"); for(var i = 0; i < lis.length ; i++){ ul.appendChild(document.createElement("li")); }

因为 Demo 2 中的 lis 是一个动态的结点列表, 每一次调用 lis 都会重新对文档进行查询,导致无限循环的问题。而 Demo 1 中的 lis 是一个静态的结点列表,是一个 li 集合的快照,对文档的任何操作都不会对其产生影响。
普遍认为:getElementsBy 系列性能比 querySelectorAll 好
querySelectorAll 返回值为一个 NodeList,而 getElementsBy 系列返回值为一个 HTMLCollection

三、NodeList 与 HTMLCollection 区别:
HTMLCollection 是元素集合而 NodeList 是节点集合(即可以包含元素,文本节点,以及注释等等)。
node.childNodes,querySelectorAll(虽然是静态的) 返回的是 NodeList,而 node.children 和 node.getElementsByXXX 返回 HTMLCollection。

四、动态作用域和静态作用域的区别:
静态作用域又称之为词法作用域:即词法作用域的函数中遇到既不是形参也不是函数内部定义的局部变量的变量时,它会根据函数定义的环境中查询。

var foo = 1;function static() { console.log(foo);}(function() { var foo = 2; static();}());

JS 的变量是遵循静态作用域的,在上述代码中会打印出 1 而非 2,因为 static 函数在作用域创建的时候,记录的 foo 是 1,如果是动态作用域的话,那么它应该打印出 2
静态作用域是产生闭包的关键,即它在代码写好之后就被静态决定它的作用域了。
动态域的函数中遇到既不是形参也不是函数内部定义的局部变量的变量时,到函数调用的环境去查询

在 JS 中,关于 this 的执行是基于动态域查询的,下面这段代码打印出 1,如果按静态作用域的话应该会打印出 2
var foo = 1;var obj = { foo: 2, bar: function() { console.log(this.foo); }};var bar = obj.bar;bar();

五、数据类型检测方式:
typeof:使用 typeof 检测数据类型,返回值有:number, string, boolean, undefined, function, object

常见的返回值就不说了,需要注意的是下面的几种情况:
console.log(typeof NaN); //numberconsole.log(typeof typeof typeof function(){}) //stringvar str = 'abc'; console.log(typeof str++); //numberconsole.log(typeof ('abc' + 1)); //stringconsole.log(typeof null); //objectconsole.log(typeof /\d/g); //objectconsole.log(typeof []); //objectconsole.log(typeof new Date()); //objectconsole.log(typeof Date()); //stringconsole.log(typeof Date); //function

instanceof:只要在当前实例的原型链上,用 instanceof 检测出来的结果都是 true,所以在类的原型继承中,最后检测出来的结果未必是正确的。

  1. 使用 instanceof 判断基本类型:
    var str1 = 'abc';var str2 = new String('abc');console.log(str1 instanceof String); //falseconsole.log(str2 instanceof String); //trueconsole.log(false instanceof Boolean); //falseconsole.log(new Boolean(false) instanceof Boolean) //true

判断基本类型还是用 typeof 吧,instanceof 不适合。

  1. 判断实例:
    function Foo(){} var foo = new Foo(); console.log(foo instanceof Foo) //true

  2. 判断继承关系:
    function Parent() {}function Child() {}Child.prototype = new Parent();Child.prototype.constructor = Child;var child = new Child();console.log(child instanceof Child); //trueconsole.log(child instanceof Parent); //trueconsole.log(child instanceof Object); //trueconsole.log(Child instanceof Function); //trueconsole.log(Function instanceof Object); //true console.log(Child instanceof Child); //false

如果你对上面输出的结果感到困惑,那建议你看下这面这篇文章:深入理解javascript原型和闭包(5)--instanceof - 王福朋 - 博客园**
constructor:检测数据类型

console.log((1).constructor === Number); //trueconsole.log("a".constructor === String); //trueconsole.log([].constructor === Array); //trueconsole.log({}.constructor === Object); //true

检测功能还是挺全面的,不过也有它的局限性:如果我们把类的原型进行重写了,在重写的过程中,很有可能把之前 constructor 给覆盖掉,这样检测出的结果就不准确了。
function Fn() {}Fn.prototype = new Array();var f = new Fn();console.log(f.constructor === Array); // true

并且 constructor 检测不出 null,undefined 的类型,所以判断类型用 constructor 也不太好用
Object.prototype.toStrong.call

Object.prototype.toStrong.call() 是检测数据类型最准确最常用的方式,
function toString(data) { return Object.prototype.toString.call(data).slice(8, -1);}console.log(toString('abc') === 'String'); console.log(toString(1) === 'Number');console.log(toString(false) === 'Boolean');console.log(toString(null) === 'Null');console.log(toString(undefined) === 'Undefined');console.log(toString([]) === 'Array');console.log(toString({}) === 'Object');console.log(toString(function(){}) === 'Function')

六、函数和对象的关系:
首先函数是一种对象:
var fn = function() {}console.log(fn instanceof Object); //true

对,函数是一种对象,但是函数却不像数组那样 ---- 你可以说数组是对象的一种,因为数组就像对象的一个子集一样,但是函数与对象之间,却不仅仅是包含和被包含的关系。
对象可以由函数创建:
function Fn() { this.name = "Lindz"; this.year = 1995;}var fn1 = new Fn(); // {name: "Lindz", year: 1995}

上面的例子很简单,它说明了对象可以通过函数重建,但是其实对象都是通过函数创建的,有人可能会反驳,他认为:
var obj = { a: 10, b: 20 };var arr = [5, true, "aa"];

但是这些都是编程中的语法糖,实际上编译器帮我们做了下面这些事:
var obj = new Object();obj.a = 10;obj.b = 20;var arr = new Array();arr[0] = 5;arr[1] = true;arr[2] = "aa";console.log(typeof (Object)); // functionconsole.log(typeof (Array)); // function

七、JS 如何判断函数是 new 调用还是普通调用
第一种方式:通过 instanceof 判断
function Person() { if(this instanceof arguments.callee) { console.log('new 调用'); }else { console.log('普通调用'); }}let p1 = new Person(); // new 调用let p2 = Person(); // 函数调用

第二种方式:通过 constructor
function Person() { if(this.constructor === arguments.callee) { console.log('new 调用'); }else { console.log('普通调用'); }}let p1 = new Person(); // new 调用let p2 = Person(); // 函数调用

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容