发表于: 2020-04-11 23:39:59

1 1648


今天完成的事情:今天学到了一下js的实用的技巧
明天计划的事情:继续后续的学习以及更多的练习
遇到的问题:实际操作还是不多还是需要多练习

收获:今天学到了一下小技巧

一、js整数的操作

使用|0和~~可以将浮点转成整型且效率方面要比同类的parseInt,Math.round 要快,在处理像素及动画位移等效果的时候会很有用。性能比较见此。

var foo = (12.4 / 4.13) | 0;//结果为3

var bar = ~~(12.4 / 4.13);//结果为3

还有一个小技巧,就是!!2个叹号,可以讲一个值,快速转化为布尔值。你可以测试一下!

var eee="eee";

alert(!!eee)

返回的是true,也就是说任何一个值前面加!!都可以恒等于true。除非这个值本来就是布尔值,或者为 undefined, null, 0, false, NaN, '',因为我提到的 undefined, null, 0, false, NaN, '' ,这些,本来就是false,所以加了两个!!之后,还是fasle。

二、重写原生alert,记录弹框次数

(function () {
      var oldAlert = window.alert,
        count = 0;
      window.alert = function (a) {
        count++;
        oldAlert(a + "\n You've called alert " + count + " times now. Stop, it's evil!");
      };
    })();
    alert("Hello Haorooms");

三、数字交换不声明中间变量的方法

两个数字之间做交换,我们的一般做法是声明一个中间变量,但是今天的做法比较奇葩,不用声明中间变量,看看是如何实现的!

var a=1,b=2;a=[b,b=a][0];

console.log('a:'+a+',b:'+b);

 //输出a:2,b:1

怎么样,这个方法是不是有一种焕然一新的感觉?

四、万物皆对象

在JavaScript的世界,万物皆对象。除了null和undefined,其他基本类型数字,字符串和布尔值都有对应有包装对象。对象的一个特征是你可以在它身上直接调用方法。

对于数字基本类型,当试图在其身上调用toString方法会失败,但用括号括起来后再调用就不会失败了,内部实现是用相应的包装对象将基本类型转为对象。所以(1).toString()相当于new Number(1).toString()。因此,你的确可以把基本类型数字,字符串,布尔等当对象使用的,只是注意语法要得体。

同时我们注意到,JavaScript中数字是不分浮点和整形的,所有数字其实均是浮点类型,只是把小数点省略了而以,比如你看到的1可以写成1.,这也就是为什么当你试图1.toString()时会报错,所以正确的写法应该是这样:1..toString(),或者如上面所述加上括号,这里括号的作用是纠正JS解析器,不要把1后面的点当成小数点。内部实现如上面所述,是将1.用包装对象转成对象再调用方法。

五、If语句的变形

当你需要写一个if语句的时候,不妨尝试另一种更简便的方法,用JavaScript中的逻辑操作符来代替。

var day = (new Date).getDay() === 0;
    //传统if语句
    if (day) {
      alert('Today is Sunday!');
    };
    //运用逻辑与代替if
    day && alert('Today is Sunday!');

比如上面的代码,首先得到今天的日期,如果是星期天,则弹窗,否则什么也不做。我们知道逻辑操作存在短路的情况,对于逻辑与表达式,只有两者都真才结果才为真,如果前面的day变量被判断为假了,那么对于整个与表达式来说结果就是假,所以就不会继续去执行后面的alert了,如果前面day为真,则还要继续执行后面的代码来确定整个表达式的真假。利用这点达到了if的效果。

对于传统的if语句,如果执行体代码超过了1 条语句,则需要加花括号,而利用逗号表达式,可以执行任意条代码而不用加花括号。

if(conditoin) alert(1),alert(2),console.log(3);

六、使用===,而不是==

我之前的一篇文章中写个 ==的隐性转换,请看:http://www.haorooms.com/post/js_yinxingleixing

==(或!=)操作符在需要的时候会自动执行类型转换。===(或!==)操作不会执行任何转换。它将比较值和类型,而且在速度上也被认为优于==。

[10] === 10    // is false
    [10] == 10    // is true
    '10' == 10     // is true
    '10' === 10    // is false
    [] == 0     // is true
      [] === 0     // is false
    '' == false   // is true but true == "a" is false
    '' === false // is false

七、使用闭包实现私有变量

 function Person(nameage) {
      this.getName = function () { return name; };
      this.setName = function (newName) { name = newName; };
      this.getAge = function () { return age; };
      this.setAge = function (newAge) { age = newAge; };

      //未在构造函数中初始化的属性
      var occupation;
      this.getOccupation = function () { return occupation; };
      this.setOccupation = function (newOcc) {
        occupation =
        newOcc;
      };
    }

八、创建对象的构造函数

function Person(firstNamelastName) {
      this.firstName = firstName;
      this.lastName = lastName;
    }

    var Saad = new Person("Saad""Mousliki");

九、小心使用typeof、instanceof和constructor

var arr = ["a""b""c"];
    typeof arr;   // return "object"
    arr instanceof Array // true
    arr.constructor();  //[]

十、创建一个自调用函数(Self-calling Funtion)

这个经常被称为自调用匿名函数(Self-Invoked Anonymous Function)或者即时调用函数表达式(IIFE-Immediately Invoked Function Expression)。这是一个在创建后立即自动执行的函数,通常如下:

(function () {
      // some private code that will be executed automatically
    })();
    (function (ab) {
      var result = a + b;
      return result;
    })(1020)

十一、从数组中获取一个随机项

var items = [12548'a'25478'foo'8852, , 'Doe'2145119];

    var randomItem = items[Math.floor(Math.random() * items.length)];

十二、在特定范围内获取一个随机数

这个代码片段在你想要生成测试数据的时候非常有用,比如一个在最小最大值之间的一个随机薪水值。

var x = Math.floor(Math.random() * (max - min + 1)) + min;

十三、在0和设定的最大值之间生成一个数字数组

var numbersArray = [] , max = 100;

for( var i=1; numbersArray.push(i++) < max;);  // numbers = [0,1,2,3 ... 100]

十四、生成一个随机的数字字母字符串

 function generateRandomAlphaNum(len) {
      var rdmString = "";
      for (; rdmString.length < lenrdmString += Math.random().toString(36).substr(2));
      return rdmString.substr(0len);
    }

//调用方法generateRandomAlphaNum(15);

十五、打乱一个数字数组

 var numbers = [5458120, -215228400122205, -85411];
    numbers = numbers.sort(function () { return Math.random() - 0.5 });
/* the array numbers will be equal for example to [120, 5, 228, -215, 400, 458, -85411, 122205]  */

十五、打乱一个数字数组

var numbers = [5458120, -215228400122205, -85411];
    numbers = numbers.sort(function () { return Math.random() - 0.5 });
/* the array numbers will be equal for example to [120, 5, 228, -215, 400, 458, -85411, 122205]  */

十七、 附加(append)一个数组到另一个数组上

    var array1 = [12"foo", { name: "Joe" }, -2458];

    var array2 = ["Doe"555100];
    Array.prototype.push.apply(array1array2);
/* array1 will be equal to  [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */


十八、将arguments对象转换成一个数组

var argArray = Array.prototype.slice.call(arguments);

【译者注:arguments对象是一个类数组对象,但不是一个真正的数组】

十九、验证参数是否是数字(number)

function isNumber(n){

    return !isNaN(parseFloat(n)) && isFinite(n);

}

二十、验证参数是否是数组

function isArray(obj){

    return Object.prototype.toString.call(obj) === '[object Array]' ;

}

注意:如果toString()方法被重写了(overridden),你使用这个技巧就不能得到想要的结果了。或者你可以使用:

Array.isArray(obj); // 这是一个新的array的方法

如果你不在使用多重frames的情况下,你还可以使用 instanceof 方法。但如果你有多个上下文,你就会得到错误的结果。

var myFrame = document.createElement('iframe');
    document.body.appendChild(myFrame);

    var myArray = window.frames[window.frames.length - 1].Array;
    var arr = new myArray(ab10); // [a,b,10]

    // instanceof will not work correctly, myArray loses his constructor
    // constructor is not shared between frames
    arr instanceof Array// false

二十一、获取一个数字数组中的最大值或最小值

var  numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];

var maxInNumbers = Math.max.apply(Math, numbers);

var minInNumbers = Math.min.apply(Math, numbers);

二十二、清空一个数组

var myArray = [12 , 222 , 1000 ];

myArray.length = 0; // myArray will be equal to [].

二十三、不要使用 delete 来删除一个数组中的项。

使用 splice 而不要使用 delete 来删除数组中的某个项。使用 delete 只是用 undefined 来替换掉原有的项,并不是真正的从数组中删除。

不要使用这种方式:

    var items = [12548'a'25478'foo'8852, , 'Doe'2154119];
    items.length// return 11
    delete items[3]; // return true
    items.length// return 11
/* items will be equal to [12, 548, "a", undefined × 1, 5478, "foo", 8852, undefined × 1, "Doe", 2154,       119]   */

而使用:

    var items = [12548'a'25478'foo'8852, , 'Doe'2154119];
    items.length// return 11
    items.splice(31);
    items.length// return 10
/* items will be equal to [12, 548, "a", 5478, "foo", 8852, undefined × 1, "Doe", 2154,       119]   */

delete 方法应该被用来删除一个对象的某个属性。

二十四、使用 length 来截短一个数组

跟上面的清空数组的方式类似,我们使用 length 属性来截短一个数组。

var myArray = [12 , 222 , 1000 , 124 , 98 , 10 ];

myArray.length = 4; // myArray will be equal to [12 , 222 , 1000 , 124].

此外,如果你将一个数组的 length 设置成一个比现在大的值,那么这个数组的长度就会被改变,会增加新的 undefined 的项补上。 数组的 length 不是一个只读属性。

myArray.length = 10; // the new array length is 10

myArray[myArray.length - 1] ; // undefined

二十五、使用逻辑 AND/OR 做条件判断

同(五),if变形语句!

   var foo = 10;
    foo == 10 && doSomething(); // 等价于 if (foo == 10) doSomething();
    foo == 5 || doSomething(); // 等价于 if (foo != 5) doSomething();

逻辑 AND 还可以被使用来为函数参数设置默认值

function doSomething(arg1) {
      Arg1 = arg1 || 10// 如果arg1没有被设置的话,Arg1将被默认设成10
    }

剩下的明天再继续


返回列表 返回列表
评论

    分享到