当前位置: 首页 > news >正文

国际网站建设常见的网络营销推广方式有哪些

国际网站建设,常见的网络营销推广方式有哪些,泊头做网站的有哪些,网站制作字怎么放在图上面大厂面试题分享 面试题库后端面试题库 (面试必备) 推荐:★★★★★地址:前端面试题库闭包的背景由于js中只有两种作用域,全局作用域和函数作用域,而在开发场景下,将变量暴露在全局作用域下的时候…

大厂面试题分享 面试题库

后端面试题库 (面试必备) 推荐:★★★★★

地址:前端面试题库

闭包的背景

由于js中只有两种作用域,全局作用域和函数作用域,而在开发场景下,将变量暴露在全局作用域下的时候,是一件非常危险的事情,特别是在团队协同开发的时候,变量的值会被无意篡改,并且极难调试分析。这样的情况下,闭包将变量封装在局部的函数作用域中,是一种非常合适的做法,这样规避掉了被其他代码干扰的情况。

闭包的使用

下面是一种最简单直接的闭包示例

//妈妈本体functionmother(){//口袋里的总钱数let money = 100//消费行为returnfunction (pay){//返回剩余钱数return money - pay}
}
//为儿子消费let payForSon = mother()
//打印最后的剩余钱数console.log(payForSon(5))
复制代码

为了便于理解,我们将外部函数比喻为妈妈本体,里面保存着总钱数这个变量和消费这个行为,通过创建为儿子消费的这个行为对象,然后执行这个行为花费5元,返回剩余的95元。

这个就是为了将变量money保存在mother本体内而避免暴露在外部的全局环境作用域中,只能通过mother()创建消费行为来影响money这个变量。

由此可以归纳总结使用闭包的三个步骤

  1. 用外层函数包裹变量,函数;

  1. 外层函数返回内层函数;

  1. 外部用变量保存外部函数返回的内层函数

目的是为了形成一个专属的变量,只在专属的作用域中操作。

上述的闭包代码示例中,有一个缺陷的场景是,在后续不需要money变量的情况下,没有释放该变量,造成内存泄露。原因是payForSon这个函数的作用域链引用着money对象,解决的办法是将payForSon = null就可以释放方法作用域,进而解除对money的引用,最后释放money变量。

闭包的扩展

函数柯里化


在开发的场景中,有时需要通过闭包来实现函数的柯里化调用。调用示例如下

alert(add(1)(2)(3))
复制代码

这种连续的传参调用函数,叫做函数柯里化。

通过闭包的实现方式如下

functionadd(a){//保存第一个参数let sum = afunctiontmp(b){//从第二个函数开始递加sum = sum + b//返回tmp,让后续可以继续传参执行return tmp}tmp.toString = function(){return sum}//返回加法函数return tmp
}
alert(add(1)(2)(3))
复制代码

下面我们来一步步分析,

  1. add(1)执行时,保存第一个参数到sum变量中,返回tmp函数

  1. add(1)(2)执行等于tmp(2),将2的值加到了变量sum上,返回tmp函数本身

  1. add(1)(2)(3)执行等同于上述步骤的加到比变量sum上,返回tmp函数本身

  1. alert(add(1)(2)(3))执行时,alert需要将值转为string显示,最后的tmp函数执行tmp.toString,返回sum的值。

矩阵点击应用


该例子的demo代码在我的github上,可以自行取阅

需求:在一个4*4的矩阵方块中,实现点击每个按钮时记录下各自的点击次数,相互之间互不干扰。

思路:在按钮事件中使用闭包,创建独立的存储变量空间。

注意:下列的方案1到方案3是逐次演进的优化方案,需要按照方案标号的次序逐层理解,更有利于理解最终的优化方案

方案1

<div id="container"></div>
...
let container = document.getElementById('container')
for (let r = 0; r < arr.length; r++) {for (let c = 0; c < arr[r].length; c++) {let cell = document.createElement('div')cell.innerHTML = `(${r},${c})`container.append(cell)cell.onclick = (function () {let n = 0return function () {n++cell.innerHTML = `点${n}`}})()}
}
复制代码

在每个按钮上通过onclick绑定闭包方法,存储操作独立的n变量,这样就可以单独记录每个按钮的点击次数

缺点:这样做有一个不足的地方是,外部无法获取内部的n变量,不能实现与外部的交互,比如按钮间的相互影响。

方案2

为了改善方案1的缺点,我们引入外部数据arr来操作管控按钮点击数。 代码示例如下:

let arr = [[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0],]
let container = document.getElementById('container')
for (let r = 0; r < arr.length; r++) {for (let c = 0; c < arr[r].length; c++) {let cell = document.createElement('div')cell.innerHTML = `(${r},${c})`container.append(cell)cell.onclick = (function (r, c) {return function () {arr[r][c]++cell.innerHTML = `点${arr[r][c]}`}})(r, c)}
}
复制代码

参照方案1 ,改动点包含两个

  • 新增arr二维数组来记录点击数,这样可以达到与外部交互的目的

  • onclick绑定的事件新增r,c两个参数,并且执行时传参进入,这样就可以把行列参数传递到方法内部(onclick的执行环境作用域与r,c所在的环境不一致,所以无法直接使用)

这样改进完以后,外部可以通过操作arr来与每个按钮的点击次数进行交互。

缺点:这样会将arr暴露在全局作用域下(可以在console控制台访问到),很容易被其他人或者模块误操作,也不利于封装

方案3

基于方案2的改进实现为,用一个立即执行的函数包裹住整个执行代码,这样就构建了一个函数作用域来封装arr变量为私有。代码如下:

(function () {let arr = [[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0],]let container = document.getElementById('container')for (let r = 0; r < arr.length; r++) {for (let c = 0; c < arr[r].length; c++) {let cell = document.createElement('div')cell.innerHTML = `(${r},${c})`container.append(cell)cell.onclick = (function (r, c) {return function () {arr[r][c]++cell.innerHTML = `点${arr[r][c]}`}})(r, c)}}})()
复制代码

这样一个相对完整的按钮点击次数的方案就完成了。

使用call实现bind


这个需要有call和bind的使用知识的前提,可以自行百度哈

废话不多说,直接上代码

Function.prototype.bind = function(obj){console.log('调用自定义bind函数');//保存当前函数对象let fun = this//去除第一个obj参数,并且转换为js数组let outerArg = Array.prototype.slice.call(arguments,1)returnfunction(){//将arguments转为js数组let innerArg = Array.prototype.slice.call(arguments)//汇总所有参数let totalArg = outerArg.concat(innerArg)//调用外部保存的函数,并且传参fun.call(obj,...totalArg)}
}//调用示例let zhangsan = {name:'wawawa'}
functiontotal(s1,s2){console.log(this.name + s1 + s2);
}
let bindTotal = total.bind(zhangsan,100)
bindTotal(200)
复制代码

重写函数类的bind函数,

  1. 先将函数对象(也就是下面示例中的total函数)保存在fun变量中,等于闭包外层保存了fun,obj以及其他绑定的参数(由于arguments是类数组对象,需要转换为数组,且去除第一个函数obj);

  1. 然后返回匿名函数,在匿名函数中,将外部和内部的参数进行转换和拼接;

  1. 最后通过fun.call(obj,...totalArg),调用保存的函数对象fun,并且通过call来实现传递绑定的作用域obj,和其他参数totalArg

注意:

  • arguments是类数组对象,不能直接使用数组方法,需要转化为数组操作

  • 外层函数arguments转化时,需要剔除掉obj,因为下面的fun.call需要单独传递obj作为函数作用域

  • totalArg传递给call函数时,需要通过...语法糖摊开数组

大厂面试题分享 面试题库

后端面试题库 (面试必备) 推荐:★★★★★

地址:前端面试题库

http://www.tj-hxxt.cn/news/64598.html

相关文章:

  • wordpress中获取当前页面urlseo求职
  • 保定建站在线培训课程
  • 国际网站模板黑帽seo是什么
  • 外贸网站建设有什么需要注意的吗自己接单的平台
  • 专注建设高端网站百度指数人群画像怎么看
  • 手机app开发网站模板今日重点新闻
  • 企业网站怎么做seo优化网站建设详细方案模板
  • 营销式网站建设营销策划的十个步骤
  • 济南网站优化建设现在做百度推广有用吗
  • 网站制作找私人多少钱简述网络营销的概念
  • 孟村做网站价格百度app官网下载
  • wordpress怎么做网站seo怎么做优化
  • 曲靖 曲靖网站建设软件(app)开发宁波网站推广优化哪家正规
  • 哪些网站做国际贸易比较好可以免费做网站推广的平台
  • 长沙手机网站建设哪些内容优化游戏性能的软件
  • 做网站用的产品展示横幅免费检测网站seo
  • iapp源码网西安百度推广优化托管
  • 做pc端网站教程搜索引擎的工作原理是什么?
  • 做网站主要学什么条件seo案例模板
  • 西宁网站设计seo短视频网页入口引流免费
  • 导航网站前端模板下载如何自己搭建网站
  • 卓光网站建设网络广告创意
  • 网站空间怎么选学生个人网页设计模板
  • 东莞常平邮编怎么优化自己网站
  • 公司网站制作导航企业如何进行品牌推广
  • 如何使用ftp上传网站北京企业网站推广哪家公司好
  • 专门做头像的网站外链生成
  • 邢台做移动网站价格表seo专业推广
  • 网站开发设计报告怎么写安徽搜索引擎优化
  • 网站推送怎么做的广州seo优化