JS的基础知识学习(一)

一、js的数据类型

JavaScript一共有8种数据类型,其中有7种基本数据类型:Undefined、Null、Boolean、Number、String、Symbol(es6新增,表示独一无二的值)和BigInt(es10新增);

二、js的数据类型转换

在 JS 中类型转换只有三种情况,分别是:

  • 转换为布尔值(调用Boolean()方法)
  • 转换为数字(调用Number()、parseInt()和parseFloat()方法)
  • 转换为字符串(调用.toString()或者String()方法)

三、js数据类型的判断

(1)typeof

typeof 对于原始类型来说,除了 null 都可以显示正确的类型

console.log(typeof 2);               // number
console.log(typeof true);            // boolean
console.log(typeof 'str');           // string
console.log(typeof []);              // object     []数组的数据类型在 typeof 中被解释为 object
console.log(typeof function(){});    // function
console.log(typeof {});              // object
console.log(typeof undefined);       // undefined
console.log(typeof null);            // object     null 的数据类型被 typeof 解释为 object

其他(数字Number,布尔值Boolean,字符串String,函数Function,对象Object,Undefined)这一些数据类型在typeof 下都被精准的解释,只有数组和null的数据类型不够精准。那么如何才能获取到 数组 和 null 的精准数据类型。这就用到下面这种方法。

(2)instanceof

console.log(2 instanceof Number);                    // false
console.log(true instanceof Boolean);                // false 
console.log('str' instanceof String);                // false  
console.log([] instanceof Array);                    // true
console.log(function(){} instanceof Function);       // true
console.log({} instanceof Object);                   // true    
// console.log(undefined instanceof Undefined);
// console.log(null instanceof Null);

以上结果显示,直接的字面量值判断数据类型,只有引用数据类型(Array,Function,Object)被精准判断,其他(数值Number,布尔值Boolean,字符串String)字面值不能被instanceof精准判断。

instanceof 在MDN中的解释:instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。其意思就是判断对象是否是某一数据类型(如Array)的实例,请重点关注一下是判断一个对象是否是数据类型的实例。在这里字面量值,2, true ,'str'不是实例,所以判断值为false。

(3)contructor

使用constructor 返回对象的构造函数

console.log((2).constructor === Number); // true
console.log((true).constructor === Boolean); // true
console.log(('str').constructor === String); // true
console.log(([]).constructor === Array); // true
console.log((function() {}).constructor === Function); // true
console.log(({}).constructor === Object); // true

创建一个对象,更改它的原型,constructor就会变得不可靠了

function Fn(){};
Fn.prototype=new Array();
var f=new Fn();
console.log(f.constructor===Fn);    // false
console.log(f.constructor===Array); // true 

(4)Object.prototype.toString.call()


var a = Object.prototype.toString;
console.log(a.call(2));//number
console.log(a.call(true));//Boolean
console.log(a.call('str'));//String
console.log(a.call([]));//Array
console.log(a.call(function(){}));//Function
console.log(a.call({}));//Object
console.log(a.call(undefined));//Undefined
console.log(a.call(null));//Null

四、null 和 undefined 的区别

typeof undefined             // undefined
typeof null                  // object
null === undefined           // false
null == undefined            // true

五、this、call、apply和bind的理解

  1. 在浏览器里,在全局范围内this 指向window对象;
  2. 在函数中,this永远指向最后调用他的那个对象;
  3. 构造函数中,this指向new出来的那个新的对象;
  4. call、apply、bind中的this被强绑定在指定的那个对象上;
  5. 箭头函数中this比较特殊,箭头函数this为父作用域的this,不是调用时的this.要知道前四种方式,都是调用时确定,也就是动态的,而箭头函数的this指向是静态的,声明的时候就确定了下来;
  6. apply、call、bind都是js给函数内置的一些API,调用他们可以为函数指定this的执行,同时也可以传参。

call、apply、bind这三个方法都可以用来改变this的指向。三者最大的区别是call和apply会改变this的指向并且立即执行函数,但是bind方法不会立即执行函数,而是会返回this改变后的函数。

(1)fn.call()
当call方法执行的时候会做三个事情:

1.首先要把操作的函数中的this关键字变为call方法第一个传递的参数。
2.把call方法第二个及以后的参数获取到
3.把要操作的函数执行,并且把第二个以后传递进来的实参传递给函数
4.如果不传参数,或者第一个参数是nullnudefinedthis都指向window

 let fn = function(a,b){
        console.log(this,a,b);
    }
    let obj = {name:"obj"};
    fn.call(obj,1,2);    // this:obj    a:1         b:2
    fn.call(1,2);        // this:1      a:2         b:undefined
    fn.call();           // this:window a:undefined b:undefined
    fn.call(null);       // this=window a=undefined b=undefined
    fn.call(undefined);  // this=window a=undefined b=undefined

 5.call中的this总是指向调用函数的对象

let obj = {
	eat(){
		console.log("吃八方财")
	}
}

function fn(){
	console.log(this); //window
	obj.eat.call(this)  // window
}
fn() // window.fn()

未创建实例,则this指向window

let obj = {
	eat(){
		console.log("吃八方财")
	}
}

function fn(){
	console.log(this); // ff
	obj.eat.call(this)  // ff
}
let ff = new fn()
ff.fn()

创建实例,则this指向实例对象。 

(2)fn.apply()

apply和call基本上一致,唯一区别在于传参方式:apply把需要传递给fn的参数放到一个数组(或者类数组)中传递进去,虽然写的是一个数组,但是也相当于给fn一个个的传递

fn.call(obj, 1, 2);
fn.apply(obj, [1, 2]);

(3)fn.bind()

bind:语法和call一模一样,区别在于立即执行还是等待执行

bind绑定的函数不立即执行,需要加括号才执行。this和参数的形式与call一样,参数是一个一个的

let obj = {
	eat(){
		console.log("吃八方财")
	}
}

function fn(name,age){
	console.log(name , age);
}
fn.bind(obj, 'xiaohong', 18)
//结果
fn(name,age){
console.log(name,age)
}

//不加括号其实返回的是绑定的函数。
//如果加上括号就会立即执行:
//xiaohong 18
fn.call(obj, 1, 2); // 改变fn中的this,并且把fn立即执行
fn.bind(obj, 1, 2); // 改变fn中的this,fn并不执行

bind函数会返回一个this改变后的函数

var a = {
    user:"追梦子",
    fn:function(e,d,f){
        console.log(this.user); //追梦子
        console.log(e,d,f); //10 1 2
    }
}
var b = a.fn;
var c = b.bind(a,10);
c(1,2);
var obj = {};

function test() {
    console.log(this === obj);
}

test(); //false

var testObj = test.bind(obj);
testObj();  //true

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值