您当前位置:首页 > 文章中心 > SCSCMS

怪异javascript解读

稿件来源: 阳光企业网站管理系统   撰稿作者: 太阳光   发表日期: 2016-02-23   阅读次数: 183   查看权限: 游客查看

怪异javascript解读

parseInt函数

parseInt('06'); // 6
parseInt('08'); // ie8及以下return 0 ;其他return 8
parseInt('010'); // ie8及以下return 8 ;其他return 10

parseInt(string[, radix]) 函数在ES3与ES5中表现不一样。当字符串以0开头时在ES3下默认以八进制解析,而ES5中以十进制解析。

x == !x

[] == ![];//true
[0] == ![0];//true

某个值等于自身的非还是比较少见的。原因在于任何对象在显性转布尔值时都是真,而执行非操作前对象会先自动执行toString()方法。

++赋值

[] == 0;    // true
+[] === 0;   // true
++[] === 1; // 报错 "赋值左侧无效"

[[]][0] === [];    // true
++[[]][0] === 1;    // true
++[[]][+[]] === 1;  // true!

如果你记住++、--(增量、减量运算符)必须是在数值里使用就好办了。+[]仅是把[]转成数字,而数组转数字会先转成字符串再转成数字。同时注意下标[]运算符号比++优先。

自动分号问题

function laugh(){
  return
  {
   haha: "ha!"
  }
}
laugh();// return nothing

var n = 1
/1*"\/\//.test(n + '"//');
console.log(n);//NaN

因随意分行造成return后自动添加了分号,而期望添加分号的反而没有添加。

prototype重写

(1) === 1; // true

Number.prototype.isOne = function () { return this === 1; };
(1).isOne(); // false!

Number.prototype.reallyIsOne = function () { return this - 1 === 0; };
(1).reallyIsOne(); // true

乍一看感觉不理解,明明是完全相等的为什么变成不相等了?原因是Number.prototype.isOne方法内的this已经不是数值基本类型,而是一个Number对象,所以不是完全相等。

alert.call.apply

alert.call.call.call.call.apply(function (a) {return a}, [1,2]) // return 2

这个怎么讲呢...

对象原始值默认调用

var foo = {
    toString: function () {
        return 5;
    },
    valueOf: function () {
        return "foo";
    }
};
alert(foo.toString() + 1); //显性调用方法
alert(foo + 1);  // "foo1" (默认调用toString)
alert(+foo);     // NaN (默认调用valueOf)

混乱的+-运算符

1 - - 1              // => 2
1 + + 1              // => 2
1 + - + 1            // => 0
1 + - + - + 1        // => 2
1 + - + - + - + 1    // => 0
1 + - + + + - + 1    // => 2
1 + / + + + / + 1    // => 1/ + + + /1

作为+运算符,在变量前起转数字功能,放在后面要么是连接符号或加法运算。最后一个主要是/ + + + /是一个正则表示式了,它转成字符串后再拼接起来。

parseInt魔法

parseInt("1", 10); // 1
parseInt("1 + 1", 10); // 1
parseInt("1" + "1", 10) // 11
parseInt("1" - "1", 10); // 0
parseInt(null, 24) === 23 // true

首先要明白parseInt并不是eval,它不会处理第一个参数字符串内的运算符,除非是表达式。针对最后一个作一下解释:以24进制去分解null时会先把null转成字符串"null",由于n在24进制中排23,而u已经不在24进制范围,所以后面的全部忽略了。

Array数组

var a = new Array(4);
console.log(a);// [undefined, undefined, undefined, undefined]
console.log(a.lenght);//undefined
a.forEach(function(){
    //no run;
});
",,," == new Array(4); // true

js对象分为特殊对象(Function)无序对象(Object)有序对象(Array),无序对象是以字符串做键值的,有序对像是以有序数字做键值的。但是并不表示Array数组不能使用字符串做键值,其实数组也支持字符串甚至小数、负数做键值,只是做枚举时无法枚举而已。

Array(len)这种只是指定数组长度,但并没真实分配数组元素。它是没真实长度lenght和不能做循环枚举,如for,forEach,map等。

[1, 2, 4] < [1, 2, 5]   // true
[1, 3, 4] < [1, 2, 5]   // false
[1, 2, 3] === [1, 2, 3]  // false
[1, 2, 3] <  [1, 2, 3]  // false
[1, 2, 3] == [1, 2, 3]  // false
[1, 2, 3] >  [1, 2, 3]  // false
[1, 2, 3] <= [1, 2, 3]   // true
[1, 2, 3] >= [1, 2, 3]   // true

首先对象判断是否相等,是判断他们分别是否引用相同的内存地址。但判断大小就会转成字符串逐个判断。

toFixed

(42).toFixed(2); // "42.00"
42.toFixed(2); // SyntaxError: identifier starts immediately after numeric literal
42.88.toFixed(2); // "42.89"
42..toFixed(2); // "42.00"
42...toFixed(2); // SyntaxError: missing name after . operator

明显toFixed只支持小数形式,如果非小数必须使用变量或者括号来引用。

编码规范

var a = b = 1;
(function(){
    var a = b = 2;
}());
console.log(b);//2

本来函数内部变量外部是无法访问的,怎么外泄了?主要是var a = b = 1这种不规范的编码造成,其实b并没有使用到var使其变成全局变量。

标签ID属性

<div id="a"></div>
<script type="text/javascript">
    a.innerHTML = "a";        // --> the div is updated
    console.log(a);           // --> the div
    window.a = 1;             // Try to set the global var "a"
    console.log(a);           // --> 1
</script>

标签里使用的id属性,默认浏览器可以使用此ID来访问此标签,等于全部变量。但如果文档中含有var a变量定义时此标签的ID属性却不能访问了。而如果使用window.a来定义的话,在此定义之前仍能访问此节点,主要原因是变量提前问题。

字符串拼接

var a = "Why am I a " + typeof + "";
var b = /[/ + "javascript"[0] + '///';//肯定是 "/[/j///" ?!
console.log(a); // "Why am I a number"
console.log(b); // "/[/ + "javascript"[0] + '/"

+''会自动转成数字0。而b的值怪是因为变成正则字符串了,[]必须成对。如果把/[/改成/\[/那就不一样了。

正则表示式

/[A-z]/.test("m"); // true
/[A-z]/.test("D"); // true
/[A-z]/.test("\\"); // true WTF?

在正则表达式中[a-b]指的是a到b的范围内,比如[ -y]表示空格到y字符之间。

var re = /[A-z]/g,i = 0,z = [],s;
for (;i < 6000; i ++){
    s = String.fromCharCode(i);
    re.test(s) && z.push(s);
}
console.log(z);
  ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O",
  "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\", "]", "^",
  "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
  "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]

关键词: wtfjs,怪异,javascript   编辑时间: 2016-02-24 15:17:20

  • 感到高兴

    9

    高兴
  • 感到支持

    9

    支持
  • 感到搞笑

    9

    搞笑
  • 感到不解

    9

    不解
  • 感到谎言

    9

    谎言
  • 感到枪稿

    9

    枪稿
  • 感到震惊

    9

    震惊
  • 感到无奈

    9

    无奈
  • 感到无聊

    9

    无聊
  • 感到反对

    9

    反对
  • 感到愤怒

    9

    愤怒
50%(9)
50%(9)
共有0 条评论 发言请遵守【相关规定

网友评论

会员头像
发 表同步腾讯微博    验证码:  点击更新请先登陆
  • 暂无评论
关闭模块文章图片 article Pictrue
  • 我的妈妈爸爸
  • 基于koa2+mysql+vue2.0+Element阳光内容管理系统
  • 代码覆盖率工具 Istanbul 入门教程
  • 全栈工程师的武器——MEAN
  • 9款超炫的 CSS3 复选框(Checkbox)
  • 微信开发在线翻译功能
  • CSS3那些不为人知的高级属性
  • 给easyui的datebox添加清空事件
  • flash写字效果
  • kendoUI系列教程之DropDownList下拉菜单
  • kendoUI系列教程之datetimepicker日期时间选择
  • kendoUI系列教程之datepicker日期选择
  • kendoUI系列教程之combobox下拉列表框
  • kendoUI系列教程之colorpicker
  • kendoUI系列教程之calendar日历表
  • kendoUI系列教程之autocomplete自动补齐