对于js一些知识点的小总结

函数声明的三种方式

  1. 函数关键字(function)
// 函数调用可以写在函数声明前面
function func(params) {
    console.log('fucntion的声明方式')
}
  1. 函数表达式或称函数字面量(Function Literals)
// 函数表达式必须等到解释器执行到那一行才进行解释,函数调用要写在函数表达式后面
// console.log(funcExp.length) //2
const funcExp = function(params,params2) {
    console.log('函数表达式声明方式')
}
// Lambda表达式(箭头函数)
const funcExp1 = params => {
    console.log('函数表达式之箭头函数声明方式')
}
  1. Function()构造函数
const funcExp2 = new Function('x','alert(1);') //alert(1)

函数调用的四种方式

  1. 声明后直接调用
// 声明一个函数并调用
function func() {
    alert("Hello World");
}
func();
// 使用函数的Lambda表达式定义函数,然后调用
var func1 = () => {
    alert("你好,程序员");
};
func1();
  1. 方法调用模式
const objFunc = {
    name: '函数',
    myFunc: () => {
        console.log('将函数赋值给对象的属性后不再称为函数称为方法')
    }
}
  1. 构造器调用模式
// 定义一个构造函数
var Person = function() {
    this.name = "程序员";
    this.sayHello = function() {
        alert("你好,这里是" + this.name);
    };
};
// 调用构造器,创建对象
var p = new Person();
// 使用对象
p.sayHello();
  1. apply、call调用模式
var func2 = function() {
    this.name = "程序员";
};
var o = {};
func2.apply(o);
alert(o.name);

操作this(call apply bind)

const name = "小明",age = 17;
const obj = {
    name: "小张",
    age: 19,
    myFunc: function(gender, country){
        console.log(this.name + "年龄:" + this.age + ",性别:" + gender + ",所在城市:" + country);
    },
}
obj.myFunc();// 小张年龄:19,性别:undefined,所在城市:undefined

const newObj = {
    name: "小红",
    age: 67
}
obj.myFunc.call(newObj, "男", "北京");    // 小红年龄:67,性别:男,所在城市:北京
obj.myFunc.apply(newObj, ["女", "广州"]);    // 小红年龄:67,性别:女,所在城市:广州 (apply传一个数组)
obj.myFunc.bind(newObj, "男", "深圳")();    // 小红年龄:67,性别:男,所在城市:深圳  (bind 返回的是一个新的函数,你必须调用它才会被执行。)
obj.myFunc.bind(newObj, ["女", "上海"])();    // 小红年龄:67,性别:女,上海,所在城市:undefined  (bind和apply传参方式一样)

const let 什么时候用

  • 只对那些在逻辑、语义和设计意图上确实不应当被改变的常量,使用 const 声明。
  • 换句话说,你认为某个量应该表现为常量,使用const。你认为某个量应该表现为可变量,就用 let。

闭包(工厂函数)

示例来自MDN

function makeAdder(x) {
    return function(y) {
        return x + y;
    };
}

var add5 = makeAdder(5);
var add10 = makeAdder(10);

console.log(add5(2));  // 7
console.log(add10(2)); // 12
var Counter = (function() {
var privateCounter = 0;
function changeBy(val) {
    privateCounter += val;
}
return {
    increment: function() {
    changeBy(1);
    },
    decrement: function() {
    changeBy(-1);
    },
    value: function() {
    return privateCounter;
    }
}
})();

console.log(Counter.value()); /* logs 0 */
Counter.increment();
Counter.increment();
console.log(Counter.value()); /* logs 2 */
Counter.decrement();
console.log(Counter.value()); /* logs 1 */

栈内存、堆内存

js数据类型
// 8种
Number、String、Boolean、Null、undefined、object、symbol、bigInt

bigInt使用

// 数字后面加n
console.log(90071992547409956n);// 12 90071992547409956n
// 构造函数形式
const bigIntNum = BigInt("9007199254740995");    
console.log(bigIntNum)// 9007199254740995n
js数据类型分类
  • 基本类型(单类型):String、Number、Boolean、null、undefined
  • 引用类型:object。包含function、array、date

NaN是Number类型中的一个特殊值

示例引导

问题:const定义的值能改吗?
答:const定义的基本类型不能改变,但是定义的对象是可以通过修改对象属性等方法来改变的,例:

const a = 1;
a = 2;
console.log(a);// Uncaught TypeError: Assignment to constant variable.
        
const b = {};
b.name = 1;
console.log(b);// {name:1}
存储类型
  • 栈内存:主要用于存储基本类型的变量,包括Boolean、Number、String、Undefined、Null、对象变量的指针
  • 堆内存:主要存储像对象这种变量类型
存储大小
  • 栈内存中的变量一般都是已知大小或者有范围上限的,算作一种简单存储。
  • 堆内存存储的对象类型数据对于大小这方面,一般都是未知的。

这也是为什么null作为一个object类型的变量却存储在栈内存中的原因。

const定义的值能改吗?的具体解释
  • 当定义const对象时,我们说的常量其实是指针,就是const对象对应的堆内存指向是不变的,但是堆内存中的数据本身的大小或者属性是可变的。
  • 当定义基础变量时,const定义的值就相当于const对象的指针,是不可变的。
new关键字

new根据构造函数生成新实例,这个时候生成的是对象,而不是基本类型。

var a = new String('123')
var b = String('123')
var c = '123'
console.log(a==b, a===b, b==c, b===c, a==c, a===c)	// true false true true true false
console.log(typeof a) // object
var a = new String('123')
var b = new String('123')
console.log(a==b, a===b)// false false
深拷贝

深拷贝是拷贝储存在内存堆中的对象,而浅拷贝是从内存栈中拷贝

// 对象的深拷贝
var clone = function (obj) { 
    if(obj === null) return null 
    if(typeof obj !== 'object') return obj;
    if(obj.constructor===Date) return new Date(obj); 
    var newObj = new obj.constructor ();  //保持继承链
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {   //不遍历其原型链上的属性
            var val = obj[key];
            newObj[key] = typeof val === 'object' ? arguments.callee(val) : val; // 使用arguments.callee解除与函数名的耦合
        }
    }  
    return newObj;  
}; 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值