JS基础

简介

本篇文章更多是自己对js的语法的简单总结,主要分为数据类型,变量,函数,隐含特性四个方面进行介绍总结。希望对你有所帮助。

数据类型

js可以分值类型(基本数据类型)和引用数据类型,其中,值类型又可以细分为:字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol(后期加的一种类型);引用数据类型:对象(Object)、数组(Array)、函数(Function)

  1. Number:包括整数型和浮点型

NaN:非数字类型,NaN类型的数据不等于自己本身,涉及到NaN的操作结果都是NaN。

isNaN(变量):判断变量是否是非数字类型。

  1. String:字符串类型
  2. Boolean:布尔类型,true false
  3. Null:对象为空,不存在
  4. Undefined:对象未定义,简单可以理解为声明未赋值。
    在实践中,null和undefined的区别并不大,只是有点细微的不同
    • 变量被声明了,但没有赋值时,就等于undefined。
    • 调用函数时,应该提供的参数没有提供,该参数等于undefined。
    • 对象没有赋值的属性,该属性的值为undefined。
    • 函数没有返回值时,默认返回undefined。
var i;
i // undefined

function f(x){console.log(x)}
f() // undefined

var  o = new Object();
o.p // undefined

var x = f();
x // undefined
  1. Array:数组的每一项可以用来保存任何类型的数据(和java不同),也就是说,可以用数组的第一个位置来保存字符串,第二个位置保存数值,第三个位置保存对象…另外,数组的大小是可以动态调整的。

创建数组的基本方式有两种

  • 第一种是使用Array构造函数,如下所示
    var colors = new Array(“red”,“blue”,“yellow”,1,true);

  • 第二种是使用数组字面量表示法,如下所示
    var colors = [“red”,“blue”,“yellow”];

  1. 对象Object,简单理解为一系列数据的集合

使用new操作符后跟Object构造函数,如下所示

var person = new Object();
person.name = "Micheal";
person.age = 24;

第二种方式是使用对象字面量表示法,如下所示

var person = {
  name : "Micheal",
  age : 24,
       eat:function(){}
};

typeof 操作符用于判断数据类型 typeof 1 —》number

变量

  1. 声明

通过var(局部变量)或let(html5支持,代码块中变量)声明:

var carname;//此时carname是undefined
var carname="Volvo";
var carname;console.log(carname);//Volvo,重新声明的不会改变原值,重新声明赋值的会改变
  1. 赋值

JS中的变量是松散类型的,可以存储任何类型的数据。instanceof可以判断变量是否是指定的引用类型,typeof一般是数据类型是什么

let x=2;
console.log(x);//2
x="hello";
console.log(x);//hello
x=function () {
    return 8;
}
console.log(x());//8

可以发现x从数值型到字符串最后到函数,都是可以进行赋值的,这和java是不同的。

  1. 变量作用域
    函数外部的变量,函数内部可以引用,函数内部的变量函数外部不可引用,变量的声明会自动提前,相似的函数的定义也会提前
var x = "hello";
(function func() {
    var x = "world";
    console.log(x);    //"world"
})();
var x = "hello";
(function func() {
    console.log(x);    //undefined,此时var x;声明提前了
    var x = "world";
})();

这里的写法涉及到函数自调用。

函数

  1. 基本使用

function 函数名(参数){
函数体

函数名可以省略,此时就是匿名函数,函数可以用变量接收,参数可以有默认值

//函数的参数可以有默认值
function add(x1, x2, x3 = 4) {
    return x1 + x2 + x3;
}
//函数可以用一个变量接收
var f1 = function (x1, x2) {
    return x1 + x2;
}

add(2, 5);//默认值可以不传
f1(2, 5,78);//可以多传参数

可以发现js的函数有很多特点:

  • 函数的参数可以有默认值
  • 函数可以用一个变量接收
  • 可以多传参数,只要顺序是对应的即可,所以没有函数重载的概念

隐含特性

  1. 自带参数arguments
function add() {
    let total = 0;
    for (let i = 0; i < arguments.length; i++) {
        total = total + arguments[i];
    }
    return total;
}

console.log(add(4, 8, 1, 6, 52, 6, 4, 5, 45, 5, 5, 6, 45, 5, 65, 6, 652));

**注意:**arguments是函数隐含的传入的参数变量数组,和函数定义的形参没有关系。比如上面的代码可以发现,即使定义的函数没有形参,调用的时候传入多个参数通过arguments可以进行累加的运算,十分方便有用。
arguments还有两个属性callee和caller。

function inner(){
    alert(arguments.callee);//指向拥有这个arguments对象的函数,即inner()
    alert(arguments.callee.caller);//这个属性保存着调用当前函数的函数的引用,即outer()
}
function outer(){
    inner();
}
outer();

**总结:

  • callee:callee是arguments对象的一个属性、用来指向当前执行的函数。
  • caller:caller是function对象的一个属性用于返回一个function引用、它返回调用它的function对象
  • 这两个属性现在并不推荐使用了

2. 自调用
顾名思义,就是函数在申明的时候顺便调用了自己,写法为:

var f1 = function add(x1, x2) {
    return x1 + x2;
};
(f1)(2, 5);

(function add(x1, x2) {
    return x1 + x2;
})(2, 5);

主要还是通过f1变量引用函数演变过来的。

  1. 闭包,闭包的定义一般为在一个嵌套函数中,内部函数引用了函数外的变量,如下
function outer(x1) {
    let f2= function (x2, x3) {
        return x1 + x2 + x3;
    };
    return f2;
}

let x1=outer(5);
console.log(x1(2.3));

一般这样的函数可以简写为:

function f1(x1) {
    return function (x2, x3) {
        return x1 + x2 + x3;
    };
}
f1(5)(2,3)

闭包的自调用更可以简化为:

(function (x1) {
    return function (x2, x3) {
        return x1 + x2 + x3;
    }
})(5)(2, 8);

闭包还有一个需要十分注意的问题,先看例子

function foo() {
    var tmp = 3;
    return function (y) {
        return ( y + (tmp++));
    }
}
var bar = foo(); // bar 现在是一个闭包
console.log(bar(1));//4
console.log(bar(1));//5
console.log(bar(1));//6

tmp变量随着bar的调用每次会自增加1,其实这也还理解,bar实际上的内部匿名函数,其中引用了一个外部变量,该变量是外部函数的局部变量,以外部变量作为参照系,temp和bar是对应起来的。只要调用的bar是同一个对象,那么tmp变量肯定也是同一个,自然也会自增加。

  1. call,apply ,bind ,这些都是函数原型里的方法

在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向。JavaScript 的一大特点是,函数存在「定义时上下文」和「运行时上下文」以及「上下文是可以改变的」这样的概念。

  • Call,Apply,改变函数的this指向
var apple= {
    color: "red",
    say: function () {
        console.log("My color is" + this.color);
    },
    helle: function () {
        console.log("hello");
    },
    hhe:function (x1,x2,x3) {
        console.log( x1+x2+x3);
    }
};
banana = {
    color: "yellow"
};

apple.say();//My color isred
apple.say.call(banana);//My color isyellow
apple.say.apply(banana);//My color isyellow
apple.helle.apply(banana);//hello
apple.hhe.call(banana,1,2,3);//6
apple.hhe.apply(banana,[1,2,3]);//6

call和apply的区别实际上只是传入参数的不同,
参数1:都是say方法中this的对象,虽然say是apple的方法,但是通过这样的转换后,this此时是banana对象,所以此时的color是banana的yellow。
参数2:call传入的是hhe函数的调用实参,用逗号分别传入,apply则是用一个数组传入实参

apple.hhe.call(banana,1,2,3);这个方法理解为:apple的hhe方法通过call转变成了banana的hhe方法,甚至可以理解为banana通过call复制了apple的hhe方法,

  • bind:改变函数的this指向,但是和call最大的不同点是bind返回的是一个函数
var bar = function (x1, x2) {
    console.log(this.x + x1 + x2);
};
var f = {
    x: 3
};
var f1 = bar.bind(f);
f1(1, 2);//6
bar

var f1 = bar.bind(f);//bar通过bind函数将其复制成了f的函数,也就是改变了bar的this指向,返回了一个新的函数对象,然后再次调用即可。
我们再来看下下面的代码:

var bar = function (x1, x2) {
    console.log(this.x + x1 + x2);
};
var f = {
    x: 3
};
bar.bind(f)(1, 2);//6
bar.call(f, 1, 2);//6
bar.apply(f, [1, 2]);//6

可以发现,他们三者的区别就是参数的传入方式不同,大家慢慢体会吧。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值