欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JavaScript函数学习总结以及相关的编程习惯指南

程序员文章站 2023-11-27 10:46:16
null 和 undefined undefined相当于一个变量并没有明确的被赋值(是否被赋值, 可能无心忽略, 逻辑问题) js的怪异之处就在于undefined真的...

null 和 undefined
undefined相当于一个变量并没有明确的被赋值(是否被赋值, 可能无心忽略, 逻辑问题) js的怪异之处就在于undefined真的是一个可以使用的值。

> var foo;
> foo
undefined

同理,当缺失参数时 javascript 会分配一个 undefined:

> function id(x) { return x }
> id()
undefined

a = 1;
a !== undefined // true

a = undefined
var b
a === b //true

null相当于变量被明确指定了没有值,而不是由于意外的原因被忽略掉了(赋值null, 正当逻辑)

参与运算
js的null如果进入运算,真的会被解析成为0或false:

(1 + null) # 1 (1 * null) # 0 (1 * null) # infinity

undefined进入运算,一律得到nan:

(1 + undefined) # nan (1 * undefined) # nan (1 / undefined) # nan

逻辑判断
null和undefined逻辑判断时都认为是false。

只用一个判断,就可以同时检验这两项是否为真:

//也会把 false, -0, +0, nan 与 '' 当成“空值”
if (v) {
  // v 有值
} else {
  // v 没有值
}

但是如果碰到大坑==的时候

var foo;
console.log(foo == null); // true
console.log(foo == undefined); // true
console.log(foo === null); // false
console.log(foo === undefined); // true
console.log(null == undefined); // true

好的做法, 一律使用===

判断一个量已定义且非空,只使用:if (a !== null && a !== undefined)。
=== 和 ==
1.==用来判断两个值是否相等

当两个值类型不同时,会发生自动转换,得到的结果非常不符合直觉,这可能不是你想要的结果。

"" == "0" // false
0 == "" // true
0 == "0" // true
false == "false" // false
false == "0" // true
false == undefined // false
false == null // false
null == undefined // true
" \t\r\n" == 0 // true

2.===

类型+值比较

"如果两边的操作数具有相同的类型和值,===返回true,!==返回false。"——《javascript:语言精粹》

最佳实践:

任何时候在比较操作中使用 === 和  !==
json操作

var person = {name :'saad', age : 26, department : {id : 15, name : "r&d"} };

var stringfromperson = json.stringify(person);
/* stringfromperson is equal to "{"name":"saad","age":26,"department":{"id":15,"name":"r&d"}}"  */

var personfromstring = json.parse(stringfromperson);
/* personfromstring is equal to person object */
to string

var obj = {
  name: 'myobj'
};

json.stringify(obj);

函数对象及匿名函数
函数对象赋值

var slice_func = [].slice
//slice_func()

var a = function() {
};
// a()

var a = {
  fun : function() {
  };
}
// a.fun()

someelement.addeventlistener("click", function(e) {
  // i'm anonymous!
});

以及

var f = function foo(){
  return typeof foo; // foo是在内部作用域内有效
};
// foo在外部用于是不可见的
typeof foo; // "undefined"
f(); // "function"

匿名函数

from

var name = 'chris';
var age = '34';
var status = 'single';
function createmember(){
// [...]
}
function getmemberdetails(){
// [...]
}
to

var myapplication = function(){
var name = 'chris';
var age = '34';
var status = 'single';
return{
createmember:function(){
// [...]
},
getmemberdetails:function(){
// [...]
}
}
}();
// myapplication.createmember() and
// myapplication.getmemberdetails() now works.

最佳实践
1.定义多个变量时,省略var关键字,用逗号代替

var someitem = 'some string';
var anotheritem = 'another string';
var onemoreitem = 'one more string';

更好的做法

var someitem = 'some string',
  anotheritem = 'another string',
  onemoreitem = 'one more string';

2.谨记,不要省略分号, 不要省略花括号

省略分号,可能导致更大的,未知的,难以发现的问题

var someitem = 'some string'
function dosomething() {
return 'something'
}

更好的做法

var someitem = 'some string';
function dosomething() {
return 'something';
}

3.使用{}代替 new ojbect()

在javascript中创建对象的方法有多种。可能是传统的方法是使用”new”加构造函数,像下面这样:

var o = new object();
o.name = 'jeffrey';
o.lastname = 'way';
o.somefunction = function() {
console.log(this.name);
}

更好的做法

var o = {}; //空对象

var o = {
name: 'jeffrey',
lastname = 'way',
somefunction : function() {
  console.log(this.name);
}
};

只要把多个全局变量都整理在一个名称空间下,拟将显著降低与其他应用程序、组件或类库之间产生糟糕的相互影响的可能性。——douglas crockford

4.使用[]代替 new array()

var a = new array();
a[0] = "joe";
a[1] = 'plumber';

更好的做法:

var a = ['joe','plumber'];

5.typeof判断

typeof一般只能返回如下几个结果:number,boolean,string,function,object,undefined

expr:

typeof xx === ''
typeof xx !== ''

e.g.

// numbers
typeof 37 === 'number';
typeof 3.14 === 'number';
typeof infinity === 'number';
typeof nan === 'number'; // 尽管nan是"not-a-number"的缩写,意思是"不是一个数字"

// strings
typeof "" === 'string';
typeof "bla" === 'string';
typeof (typeof 1) === 'string'; // typeof返回的肯定是一个字符串

// booleans
typeof true === 'boolean';
typeof false === 'boolean';

// undefined
typeof undefined === 'undefined';
typeof blabla === 'undefined'; // 一个未定义的变量,或者一个定义了却未赋初值的变量

// objects
typeof {a:1} === 'object';
typeof [1, 2, 4] === 'object'; // 使用array.isarray或者object.prototype.tostring.call方法可以分辨出一个数组和真实的对象
typeof new date() === 'object';

// functions
typeof function(){} === 'function';
typeof math.sin === 'function';

typeof null === 'object'; // 从javascript诞生以来,一直是这样的.

6.三元运算符 :强大且风骚

语法

expression ? xxx : yyy
bad

var direction;
if(x < 200){
 direction = 1;
} else {
 direction = -1;
}
good

var direction = x < 200 ? 1 : -1;

7.使用逻辑 and/or 做条件判断

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

//默认值
a = b || 'default'
return b || c || d > 1 ? 0 : 2

8.给一个变量赋值的时候不要忘记使用var关键字

给一个未定义的变量赋值会导致创建一个全局变量。要避免全局变量

9.自我调用的函数

自调用匿名函数(self-invoked anonymous function)或者即时调用函数表达式(iife-immediately invoked function expression)。这是一个在创建后立即自动执行的函数

(function(){
  // some private code that will be executed automatically
})();

(function(a,b){
  var result = a+b;
  return result;
})(10,20)

10.避免使用 eval() 和 function 构造函数

eval=邪恶, 不仅大幅降低脚本的性能(译注:jit编译器无法预知字符串内容,而无法预编译和优化),而且这也会带来巨大的安全风险,因为这样付给要执行的文本太高的权限,避而远之

使用 eval 和 function 构造函数是非常昂贵的操作,因为每次他们都会调用脚本引擎将源代码转换成可执行代码。

var func1 = new function(functioncode);
var func2 = eval(functioncode);

11.避免使用 with()

使用 with() 会插入一个全局变量。因此,同名的变量会被覆盖值而引起不必要的麻烦

12.脚本放在页面的底部

记住——首要目标是让页面尽可能快的呈献给用户,脚本的夹在是阻塞的,脚本加载并执行完之前,浏览器不能继续渲染下面的内容。因此,用户将*等待更长时间

13.避免在for语句内声明变量

bad

for(var i = 0; i < somearray.length; i++) {
var container = document.getelementbyid('container');
container.innerhtml += 'my number: ' + i;
console.log(i);
}

good

var container = document.getelementbyid('container');
for(var i = 0, len = somearray.length; i < len; i++) {
container.innerhtml += 'my number: ' + i;
console.log(i);
}

14.给代码添加注释

// 循环数组,输出每项名字(译者注:这样的注释似乎有点多余吧).
for(var i = 0, len = array.length; i < len; i++) {
console.log(array[i]);
}

15.instanceof

instanceof 方法要求开发者明确地确认对象为某特定类型

var ostringobject = new string("hello world");
console.log(ostringobject instanceof string);  // 输出 "true"

// 判断 foo 是否是 foo 类的实例
function foo(){}
var foo = new foo();
console.log(foo instanceof foo)//true

// 判断 foo 是否是 foo 类的实例 , 并且是否是其父类型的实例
function aoo(){}
function foo(){}
foo.prototype = new aoo();//javascript 原型继承

var foo = new foo();
console.log(foo instanceof foo)//true
console.log(foo instanceof aoo)//true

16.apply/call

somefn.call(this, arg1, arg2, arg3);
somefn.apply(this, [arg1, arg2, arg3]);

apply

function.apply(obj,args)方法能接收两个参数

obj:这个对象将代替function类里this对象
args:这个是数组,它将作为参数传给function(args-->arguments)
call

function.call(obj,[param1[,param2[,…[,paramn]]]])

obj:这个对象将代替function类里this对象
params:这个是一个参数列表
使用哪个取决于参数的类型